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.rti;
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 * RTI Timer Peripheral Manager.
49 *
50 * This Timer module manages the RTI timer peripheral(s) available on the ARM
51 * and C6000 devices (see {@link ./doc-files/TimerTables.html Timer Mapping Tables}
52 * for supported device information).
53 *
54 * @p(html)
55 * <h3> Calling Context </h3>
56 * <table border="1" cellpadding="3">
57 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
58 *
59 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
60 * <!-- -->
61 * <tr><td> {@link #getNumTimers} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
62 * <tr><td> {@link #getStatus} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
63 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
64 * <tr><td> {@link #construct} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
65 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
66 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
67 * <tr><td> {@link #destruct} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
68 * <tr><td> {@link #getCount} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
69 * <tr><td> {@link #getFreq} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
70 * <tr><td> {@link #getPeriod} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
71 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
72 * <tr><td> {@link #setPeriod} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
73 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
74 * <tr><td> {@link #start} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
75 * <tr><td> {@link #stop} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
76 * <tr><td colspan="6"> Definitions: <br />
77 * <ul>
78 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
79 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
80 * <li> <b>Task</b>: API is callable from a Task thread. </li>
81 * <li> <b>Main</b>: API is callable during any of these phases: </li>
82 * <ul>
83 * <li> In your module startup after this module is started (e.g. Timer_Module_startupDone() returns TRUE). </li>
84 * <li> During xdc.runtime.Startup.lastFxns. </li>
85 * <li> During main().</li>
86 * <li> During BIOS.startupFxns.</li>
87 * </ul>
88 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
89 * <ul>
90 * <li> During xdc.runtime.Startup.firstFxns.</li>
91 * <li> In your module startup before this module is started (e.g. Timer_Module_startupDone() returns FALSE).</li>
92 * </ul>
93 * </ul>
94 * </td></tr>
95 *
96 * </table>
97 * @p
98 *
99 */
100 @ModuleStartup
101
102 module Timer inherits ti.sysbios.interfaces.ITimer
103 {
104 /*! Max value of Timer period for PeriodType_COUNTS*/
105 const UInt MAX_PERIOD = 0xffffffff;
106
107 /*! @_nodoc
108 * Min instructions to use in trigger().
109 */
110 const Int MIN_SWEEP_PERIOD = 8;
111
112 /*! Timer Settings. */
113 metaonly struct TimerSetting {
114 Ptr baseAddr; /*! specify the base address */
115 Int intNum; /*! specify which interrupt vector */
116 Int eventId; /*! specify which event number to use */
117 String name; /*! specify the timer name */
118 };
119
120 /*! @_nodoc */
121 @XmlDtd
122 metaonly struct BasicView {
123 Ptr halTimerHandle;
124 String label;
125 UInt id;
126 String name;
127 String startMode;
128 String runMode;
129 UInt periodInCounts;
130 UInt periodInMicroSecs;
131 UInt intNum;
132 Int eventId;
133 String tickFxn[];
134 UArg arg;
135 String extFreq;
136 String hwiHandle;
137 };
138
139 /*! @_nodoc */
140 metaonly struct DeviceView {
141 UInt id;
142 String device;
143 String devAddr;
144 UInt intNum;
145 String runMode;
146 UInt period;
147 String state;
148 };
149
150 /*! @_nodoc */
151 metaonly struct ModuleView {
152 String availMask;
153 String intFrequency[];
154 }
155
156 /*! @_nodoc */
157 @Facet
158 metaonly config ViewInfo.Instance rovViewInfo =
159 ViewInfo.create({
160 viewMap: [
161 [
162 'Basic',
163 {
164 type: ViewInfo.MODULE_DATA,
165 viewInitFxn: 'viewInitBasic',
166 structName: 'BasicView'
167 }
168 ],
169 [
170 'Device',
171 {
172 type: ViewInfo.INSTANCE,
173 viewInitFxn: 'viewInitDevice',
174 structName: 'DeviceView'
175 }
176 ],
177 [
178 'Module',
179 {
180 type: ViewInfo.MODULE,
181 viewInitFxn: 'viewInitModule',
182 structName: 'ModuleView'
183 }
184 ],
185 ]
186 });
187
188 /*!
189 * ======== A_invalidTimer ========
190 * Assert raised when timer id specified is not supported.
191 */
192 config xdc.runtime.Assert.Id A_invalidTimer = {
193 msg: "A_invalidTimer: Invalid Timer Id."
194 };
195
196 /*!
197 * Error raised when timer id specified is not supported.
198 */
199 config Error.Id E_invalidTimer =
200 {msg: "E_invalidTimer: Invalid Timer Id %d"};
201
202 /*!
203 * Error raised when timer requested is in use
204 */
205 config Error.Id E_notAvailable =
206 {msg: "E_notAvailable: Timer not available %d"};
207
208 /*!
209 * Error raised when Hwi Params has mask where self is turned on.
210 *
211 * This is not allowed because the timers on this platform do not
212 * support one-shot mode and a stub is used to stop it.
213 * Another timer interrupt cannot go off when the ISR is running.
214 */
215 config Error.Id E_invalidHwiMask =
216 {msg: "E_InvalidMask: Mask in hwiParams cannot enable self"};
217
218 /*!
219 * Error raised when period requested is not supported
220 */
221 config Error.Id E_cannotSupport =
222 {msg: "E_cannotSupport: Timer cannot support requested period %d"};
223
224 /*!
225 * ======== anyMask ========
226 * Available mask to be used when select = Timer_ANY
227 */
228 config UInt anyMask;
229
230 /*!
231 * ======== continueOnSuspend ========
232 * Continue counting during emulation halt. Default is false.
233 *
234 * When false, timer stops counting during emulation halt. When true,
235 * timer continues to count during emulation halt.
236 */
237 config Bool continueOnSuspend = false;
238
239 /*!
240 * ======== intFreqs ========
241 * Default internal timer input clock frequency array.
242 *
243 * This array can be used to change the input clock frequency
244 * for a particular timer.
245 *
246 * For example, if it is required to change the input clock frequency
247 * for timer id 1 to 200MHz on a device that has 2 timers, the
248 * intFreqs[1] config param can be set to {hi:0, lo:200000000} in the
249 * config script.
250 *
251 * @p(code)
252 * var Timer = xdc.useModule('ti.sysbios.timers.rti.Timer');
253 * Timer.intFreqs[1].lo = 200000000; // = CPU freq
254 * Timer.intFreqs[1].hi = 0;
255 * @p
256 */
257 metaonly config Types.FreqHz intFreqs[];
258
259 /*!
260 * ======== timerSettings ========
261 * Global Control configuration for each physical timer.
262 */
263 metaonly config TimerSetting timerSettings[] = [];
264
265 /*!
266 * @_nodoc
267 * RTI timer registers.
268 */
269 struct DeviceRegs {
270 UInt32 RTIGCTRL; /*! 0x00h */
271 UInt32 RTITBCTRL; /*! 0x04h */
272 UInt32 RTICAPCTRL; /*! 0x08h */
273 UInt32 RTICOMPCTRL; /*! 0x0Ch */
274 UInt32 RTIFRC0; /*! 0x10h */
275 UInt32 RTIUC0; /*! 0x14h */
276 UInt32 RTICPUC0; /*! 0x18h */
277 UInt32 RESERVED0; /*! 0x1Ch */
278 UInt32 RTICAFRC0; /*! 0x20h */
279 UInt32 RTICAUC0; /*! 0x24h */
280 UInt32 RESERVED1; /*! 0x28h */
281 UInt32 RESERVED2; /*! 0x2Ch */
282 UInt32 RTIFRC1; /*! 0x30h */
283 UInt32 RTIUC1; /*! 0x34h */
284 UInt32 RTICPUC1; /*! 0x38h */
285 UInt32 RESERVED3; /*! 0x3Ch */
286 UInt32 RTICAFRC1; /*! 0x40h */
287 UInt32 RTICAUC1; /*! 0x44h */
288 UInt32 RESERVED4; /*! 0x48h */
289 UInt32 RESERVED5; /*! 0x4Ch */
290 UInt32 RTICOMP0; /*! 0x50h */
291 UInt32 RTIUDCP0; /*! 0x54h */
292 UInt32 RTICOMP1; /*! 0x58h */
293 UInt32 RTIUDCP1; /*! 0x5Ch */
294 UInt32 RTICOMP2; /*! 0x60h */
295 UInt32 RTIUDCP2; /*! 0x64h */
296 UInt32 RTICOMP3; /*! 0x68h */
297 UInt32 RTIUDCP3; /*! 0x6Ch */
298 UInt32 RTITBLCOMP; /*! 0x70h */
299 UInt32 RTITBLHCOMP; /*! 0x74h */
300 UInt32 RESERVED6; /*! 0x78h */
301 UInt32 RESERVED7; /*! 0x7Ch */
302 UInt32 RTISETINTENA; /*! 0x80h */
303 UInt32 RTICLEARINTENA; /*! 0x84h */
304 UInt32 RTIINTFLAG; /*! 0x88h */
305 UInt32 RESERVED8; /*! 0x8Ch */
306 UInt32 RTIDWDCTRL; /*! 0x90h */
307 UInt32 RTIDWDPRLD; /*! 0x94h */
308 UInt32 RTIWDSTATUS; /*! 0x98h */
309 UInt32 RTIWDKEY; /*! 0x9Ch */
310 UInt32 RTIDWDCNTR; /*! 0xA0h */
311 UInt32 RTIWWDRXNCTRL; /*! 0xA4h */
312 UInt32 RTIWWDSIZECTRL; /*! 0xA8h */
313 UInt32 RTIINTCLRENABLE; /*! 0xACh */
314 UInt32 RTICOMP0CLR; /*! 0xB0h */
315 UInt32 RTICOMP1CLR; /*! 0xB4h */
316 UInt32 RTICOMP2CLR; /*! 0xB8h */
317 UInt32 RTICOMP3CLR; /*! 0xBCh */
318 };
319
320 /*!
321 * ======== oneShotStub ========
322 * @_nodoc
323 * RTI timer does not support one shot mode. This stub stops timer
324 * and disables its interrupt.
325 *
326 * @param(arg) Timer Handle.
327 */
328 Void oneShotStub(UArg arg);
329
330 /*!
331 * ======== periodicStub ========
332 * @_nodoc
333 *
334 * @param(arg) Timer Handle.
335 */
336 Void periodicStub(UArg arg);
337
338 /*!
339 * ======== getHandle ========
340 * @_nodoc
341 * Used by TimestampProvider module to get hold of timer handle used by
342 * Clock.
343 *
344 * @param(id) timer Id.
345 */
346 Handle getHandle(UInt id);
347
348 instance:
349
350 /*!
351 * ======== createHwi ========
352 * Controls whether the timer module creates a Hwi. Default is true.
353 *
354 * If an application needs to create a Hwi for the timer, it is possible
355 * to indicate to the timer module to not create a Hwi by setting this
356 * param to false. This feature may be useful if the application needs to
357 * create a Hwi using the family specific Hwi module or on certain ARM
358 * targets create a Hwi of FIQ type to minimize latency.
359 *
360 * If the application creates its own Hwi, it needs to select an interrupt
361 * number corresponding to the timer Id (see
362 * {@link ./doc-files/TimerTables.html Timer Mapping Tables}).
363 *
364 * Here's an example for the Cortex-R4 target that creates a custom
365 * Hwi of FIQ type and sets "Timer.createHwi" param to false when
366 * creating a Timer object, in order to prevent the Timer module from
367 * creating a Hwi.
368 *
369 * @p(code)
370 * *.cfg:
371 * xdc.useModule('ti.sysbios.timers.rti.Timer');
372 * xdc.useModule('ti.sysbios.family.arm.v7r.vim.Hwi');
373 *
374 * *.c:
375 * #include <xdc/std.h>
376 * #include <xdc/runtime/Error.h>
377 *
378 * #include <ti/sysbios/timers/rti/Timer.h>
379 * #include <ti/sysbios/family/arm/v7r/vim/Hwi.h>
380 * ...
381 *
382 * Timer_Struct timer0;
383 * Timer_Handle handle0;
384 *
385 * interrupt Void myIsr()
386 * {
387 * // Timer needs to be stopped only if run mode is One shot.
388 * // For periodic run mode, this function needs to only ack
389 * // the timer interrupt.
390 * Timer_stop(handle0);
391 * Timer_ackInterrupt(handle0);
392 * ...
393 * }
394 *
395 * Int main(Int argc, char* argv[])
396 * {
397 * Timer_Params timerParams;
398 * Hwi_Params hwiParams;
399 * Error_Block eb;
400 *
401 * Error_init(&eb);
402 *
403 * // The interrupt number corresponding to a given Timer Id
404 * // can be determined from the Timer Mapping table. A link
405 * // to the table can be found in this document.
406 * Hwi_Params_init(&hwiParams);
407 * hwiParams.type = Hwi_Type_FIQ;
408 * Hwi_create(2, (Hwi_FuncPtr)(&myIsr), &hwiParams, &eb);
409 *
410 * Timer_Params_init(&timerParams);
411 * timerParams.period = 60000;
412 * timerParams.runMode = Timer_RunMode_ONESHOT;
413 * timerParams.periodType = Timer_PeriodType_MICROSECS;
414 * timerParams.createHwi = FALSE;
415 * Timer_construct(&timer0, 0, NULL, &timerParams, &eb);
416 *
417 * handle0 = Timer_handle(&timer0);
418 * ...
419 *
420 * BIOS_start();
421 * return(0);
422 * }
423 * @p
424 */
425 config Bool createHwi = true;
426
427 /*!
428 * ======== hwiParams ========
429 * Hwi Params for Hwi Object. Default is null.
430 */
431 config Hwi.Params *hwiParams = null;
432
433 /*!
434 * ======== prescale ========
435 * Prescale factor. Default is 1 (0 is not recommended).
436 *
437 * The Prescale factor can be used to achieve longer timer periods.
438 * With a prescale factor specified, the actual timer period is
439 * period * (prescale + 1).
440 */
441 config UInt8 prescale = 1;
442
443 /*!
444 * ======== reconfig ========
445 * Used to modify static timer instances at runtime.
446 *
447 * @param(timerParams) timer Params
448 * @param(tickFxn) functions that runs when timer expires.
449 */
450 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
451
452 /*!
453 * ======== ackInterrupt ========
454 * clear the current timer interrupt flag
455 */
456 Void ackInterrupt();
457
458 internal:
459
460 /*! Information about timer */
461 struct TimerDevice {
462 Int intNum;
463 Int eventId;
464 Ptr baseAddr;
465 };
466
467 /*!
468 * ======== startupNeeded ========
469 * Flag used to prevent misc code from being brought in
470 * un-necessarily
471 */
472 config UInt startupNeeded = false;
473
474 /*!
475 * ======== numTimerDevices ========
476 * The number of logical timers on a device.
477 */
478 config Int numTimerDevices;
479
480 481 482 483
484 Void initDevice(Object *timer);
485
486 487 488 489
490 Int postInit(Object *timer, Error.Block *eb);
491
492 493 494
495 Bool checkOverflow(UInt32 a, UInt32 b);
496
497 struct Instance_State {
498 Bool staticInst;
499 Int id;
500 ITimer.RunMode runMode;
501 ITimer.StartMode startMode;
502 UInt prescale;
503 UInt period;
504 ITimer.PeriodType periodType;
505 UInt intNum;
506 UArg arg;
507 Hwi.FuncPtr tickFxn;
508 Types.FreqHz extFreq;
509 Hwi.Handle hwi;
510 Bool createHwi;
511 }
512
513 struct Module_State {
514 UInt availMask;
515 TimerDevice device[];
516 Types.FreqHz intFreqs[];
517 Handle handles[];
518 }
519 }