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