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.family.c28;
39
40 import xdc.rov.ViewInfo;
41
42 import xdc.runtime.Error;
43 import xdc.runtime.Assert;
44 import xdc.runtime.Types;
45 import ti.sysbios.interfaces.ITimer;
46
47 /*!
48 * ======== Timer ========
49 * Timer peripherals manager for the c28 family.
50 *
51 * @p(html)
52 * <h3> 28x Timers </h3>
53 * @p(blist)
54 * - The 28x has three 32-bit timers.
55 * - The 28x timer counts downward from 'period' to 0; however, Timer_getCount
56 * will count upward.
57 * - The 28x timer supports an optional 16-bit prescalar. The prescalar
58 * effectively sets the period of the timer tick; the prescalar counts down
59 * from the prescale factor to 0, then a timer tick occurs. So, with a
60 * prescale set, the actual timer period is (prescale * period).
61 * @p
62 *
63 * @p(html)
64 * <h3> Calling Context </h3>
65 * <table border="1" cellpadding="3">
66 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
67 *
68 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
69 * <!-- -->
70 * <tr><td> {@link #getNumTimers} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
71 * <tr><td> {@link #getStatus} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
72 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
73 * <tr><td> {@link #construct} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
74 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
75 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
76 * <tr><td> {@link #destruct} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
77 * <tr><td> {@link #getCount} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
78 * <tr><td> {@link #getFreq} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
79 * <tr><td> {@link #getPeriod} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
80 * <tr><td> {@link #getPrescale} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
81 * <tr><td> {@link #getPrescaleCount} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
82 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
83 * <tr><td> {@link #setPeriod} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
84 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
85 * <tr><td> {@link #setPrescale} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
86 * <tr><td> {@link #start} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
87 * <tr><td> {@link #stop} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
88 * <tr><td colspan="6"> Definitions: <br />
89 * <ul>
90 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
91 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
92 * <li> <b>Task</b>: API is callable from a Task thread. </li>
93 * <li> <b>Main</b>: API is callable during any of these phases: </li>
94 * <ul>
95 * <li> In your module startup after this module is started (e.g. Timer_Module_startupDone() returns TRUE). </li>
96 * <li> During xdc.runtime.Startup.lastFxns. </li>
97 * <li> During main().</li>
98 * <li> During BIOS.startupFxns.</li>
99 * </ul>
100 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
101 * <ul>
102 * <li> During xdc.runtime.Startup.firstFxns.</li>
103 * <li> In your module startup before this module is started (e.g. Timer_Module_startupDone() returns FALSE).</li>
104 * </ul>
105 * </ul>
106 * </td></tr>
107 * </table>
108 * @p
109 */
110
111 @InstanceFinalize
112 @InstanceInitError
113 @ModuleStartup
114
115 module Timer inherits ti.sysbios.interfaces.ITimer
116 {
117 /*! Max value of Timer period for PeriodType_COUNTS*/
118 const UInt MAX_PERIOD = 0xffffffff;
119
120 /*! Number of timer peripherals on chip */
121 const Int NUM_TIMER_DEVICES = 3;
122
123 /*! Timer Emulation Mode. */
124 struct EmulationMode {
125 UInt free; /*! At sw breakpoint, stop or free-run the timer. */
126 UInt soft; /*! At sw breakpoint, hard stop or run down timer. */
127 };
128
129 /*! @_nodoc */
130 metaonly struct BasicView {
131 Ptr halTimerHandle;
132 String label;
133 UInt id;
134 String startMode;
135 String runMode;
136 UInt period;
137 String periodType;
138 UInt prescalar;
139 UInt intNum;
140 UArg arg;
141 String tickFxn[];
142 String hwiHandle;
143 };
144
145 /*! @_nodoc */
146 metaonly struct DeviceView {
147 UInt id;
148 String deviceAddr;
149 UInt intNum;
150 UInt period;
151 UInt currCount;
152 UInt remainingCount;
153 };
154
155 /*! @_nodoc */
156 @Facet
157 metaonly config ViewInfo.Instance rovViewInfo =
158 ViewInfo.create({
159 viewMap: [
160 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
161 ['Device', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitDevice', structName: 'DeviceView'}],
162 ]
163 });
164
165 /*!
166 * Assert raised in Timer_create when timer id specified is not supported.
167 */
168 config Assert.Id A_invalidTimer = {
169 msg: "A_invalidTimer: Timer id must be 0-2"
170 };
171
172 /*!
173 * Error raised in Timer_create when timer requested is in use.
174 */
175 config Error.Id E_notAvailable = {
176 msg: "E_notAvailable: Timer not available %d"
177 };
178
179 /*!
180 * Assert raised in Timer_create if an invalid RunMode is requested.
181 */
182 config Assert.Id A_invalidRunMode = {
183 msg: "A_invalidRunMode: Invalid RunMode"
184 };
185
186 /*!
187 * Assert raised in Timer_create when Hwi Params does not mask 'self'.
188 *
189 * This is not allowed because the timers on this platform do not
190 * inherently support one-shot mode. Instead, a stub is used to stop the
191 * timer, so it is important that the timer interrupt not occur again
192 * before the stub has stopped the timer.
193 */
194 config Assert.Id A_invalidHwiMask = {
195 msg: "A_InvalidMask: Mask in hwiParams cannot enable self"
196 };
197
198 /*!
199 * Assert raised when period requested is not supported.
200 */
201 config Assert.Id E_cannotSupport = {
202 msg: "E_cannotSupport: Timer cannot support requested period"
203 };
204
205 /*!
206 * ======== anyMask ========
207 * Available mask to be used when select = Timer_ANY
208 */
209 config UInt anyMask = 0x7;
210
211 instance:
212
213 /*!
214 * ======== emulationModeInit ========
215 * Initial timer emulation mode. Default hard stop.
216 *
217 * Determines timer state at a software breakpoint. If 'free' is 1, the
218 * timer will continue to run, and the value of 'soft' doesn't matter.
219 * When 'free' is 0 and 'soft' is 1, the timer runs down to 0 then stops.
220 * When 'free' is 0 and 'soft' is 0, the timer halts.
221 *
222 * @p(html)
223 * <pre>
224 * FREE SOFT
225 * 0 0 Stop after next timer decrement. (Hard stop)
226 * 0 1 Stop after timer runs down to 0. (Soft stop)
227 * 1 x Continue running the timer.
228 * </pre>
229 */
230 config EmulationMode emulationModeInit = {free: 0, soft: 0};
231
232 /*!
233 * ======== prescale ========
234 * Prescale factor.
235 *
236 * The prescale factor determines the length of a timer tick.
237 * If a prescale of 10 is specified, a timer tick will occur
238 * every 11 cycles.
239 *
240 * If the timer is used as a counter, the prescale factor determines
241 * the period between counts. Otherwise, the prescale factor can be used
242 * to achieve longer timer periods: with a prescale specified, the actual
243 * period is (period * prescale+1).
244 */
245 config UInt16 prescale = 0;
246
247 /*!
248 * ======== hwiParams ========
249 * Parameters for the Hwi object created for the Timer ISR.
250 *
251 * The mask setting for the Hwi object should include SELF to prevent
252 * nested timer interrupts.
253 */
254 config Hwi.Params *hwiParams = null;
255
256 /*!
257 * ======== getCount ========
258 * Returns the number of counts that have passed.
259 *
260 * The 28x timer counts downward from the period to 0, but getCount
261 * subtracts the timer counter value from the period so that getCount
262 * counts upward instead of downward.
263 *
264 * @b(returns) timer counts, counting upward from 0
265 */
266 @DirectCall
267 override UInt32 getCount();
268
269 /*!
270 * ======== setPreScale ========
271 * Set timer prescale value.
272 *
273 * This function sets the value of the prescalar, and will also reload
274 * the timer counter and prescale registers.
275 *
276 * The prescalar decrements with each timer clock source cycle until it
277 * reaches zero, then the timer's count is decremented by one. The
278 * prescalar has the effect of setting the rate of the timer tick.
279 *
280 * @param(preScalar) The value to set the prescale period to.
281 */
282 Void setPrescale(UInt16 preScalar);
283
284 /*!
285 * ======== getPrescale ========
286 * Get timer prescale value.
287 *
288 * This is not the prescale count, but the period of the prescalar.
289 *
290 * @b(returns) prescale value
291 */
292 UInt16 getPrescale();
293
294 /*!
295 * ======== getPrescaleCount ========
296 * Reads timer prescale counter.
297 *
298 * The prescale counter counts down from prescale to 0, but
299 * getPrescaleCount subtracts the counter value from the period so that
300 * this function counts upward instead of downward.
301 *
302 * @b(returns) prescale counter, counting upward from 0
303 */
304 UInt16 getPrescaleCount();
305
306 /*!
307 * ======== getExpiredCounts64 ========
308 * @_nodoc
309 * Called by TimestampProvider to read the timer counter, accounting
310 * for counter rollover.
311 *
312 * This version of the API returns a 64-bit count and is only used when
313 * the TimestampProvider is using a dedicated timer.
314 *
315 * This function must be called with interrupts disabled.
316 *
317 * @b(returns) Timer counts, accounting for counter rollover.
318 */
319 @DirectCall
320 Void getExpiredCounts64(Types.Timestamp64 *result);
321
322 /*!
323 * ======== reconfig ========
324 * Used to modify timer instances at runtime.
325 *
326 * @param(timerParams) timer Params
327 * @param(tickFxn) functions that runs when timer expires
328 */
329 @DirectCall
330 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
331
332 internal:
333
334 335 336 337
338 Int postInit(Object *timer, Error.Block *eb);
339
340 341 342
343 Void stopAndClear(Object *timer);
344
345 346 347
348 Bool checkOverflow(UInt32 a, UInt32 b);
349
350 /*!
351 * ======== oneShotStub ========
352 * This stub implements oneShot mode by stopping the timer and clearing
353 * the CPU IFR bit. It does not clear the PIEIFR bit, so timer 0 does
354 * not support one shot mode.
355 *
356 * @param(arg) The timer object
357 */
358 Void oneShotStub(UArg arg);
359
360 /*!
361 * ======== startupNeeded ========
362 * Flag used to prevent Module_startup and Timer_startup code from being
363 * brought in unnecessarily. Flag is set if there are any static Timer
364 * instances.
365 */
366 config UInt startupNeeded = false;
367
368 config UInt8 intNumDef[3];
369
370 struct Instance_State {
371 Int id;
372 EmulationMode emulationModeInit;
373 ITimer.RunMode runMode;
374 ITimer.StartMode startMode;
375 UInt32 period;
376 ITimer.PeriodType periodType;
377 UInt16 prescale;
378 UInt intNum;
379 UArg arg;
380 Hwi.FuncPtr tickFxn;
381 Types.FreqHz extFreq;
382 Hwi.Handle hwi;
383 }
384
385 struct Module_State {
386 Char availMask;
387 Handle staticTimers[NUM_TIMER_DEVICES]; 388
389 }
390 }