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.family.arm.f2838x;
37
38 import xdc.rov.ViewInfo;
39
40 import xdc.runtime.Error;
41 import xdc.runtime.Assert;
42 import xdc.runtime.Types;
43 import ti.sysbios.interfaces.ITimer;
44 import ti.sysbios.family.arm.m3.Hwi;
45
46 /*!
47 * ======== Timer ========
48 * Timer peripheral manager for the CPU timers (the C28-type timers
49 * provisioned for the CM).
50 *
51 * @p(html)
52 * <h3> CPU Timers </h3>
53 * @p(blist)
54 * - The CM has three 32-bit CPU timers.
55 * - The CPU timers count downward from 'period' to 0; however, Timer_getCount
56 * will count upward.
57 * - The CPU timer supports an optional 16-bit prescaler. The prescaler
58 * effectively sets the period of the timer tick; the prescaler 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 @ModuleStartup
112 @InstanceInitStatic
113
114 module Timer inherits ti.sysbios.interfaces.ITimer
115 {
116 /*! Max value of Timer period for PeriodType_COUNTS*/
117 const UInt MAX_PERIOD = 0xffffffff;
118
119 /*! Number of timer peripherals on chip */
120 const Int NUM_TIMER_DEVICES = 3;
121
122 /*! Timer Emulation Mode. */
123 struct EmulationMode {
124 UInt free; /*! At sw breakpoint, stop or free-run the timer. */
125 UInt soft; /*! At sw breakpoint, hard stop or run down timer. */
126 };
127
128 /*! @_nodoc */
129 metaonly struct BasicView {
130 Ptr halTimerHandle;
131 String label;
132 UInt id;
133 String startMode;
134 String runMode;
135 UInt period;
136 String periodType;
137 UInt prescaler;
138 UInt intNum;
139 UArg arg;
140 String tickFxn[];
141 String hwiHandle;
142 };
143
144 /*! @_nodoc */
145 metaonly struct DeviceView {
146 UInt id;
147 String deviceAddr;
148 UInt intNum;
149 };
150
151 /*! @_nodoc */
152 @Facet
153 metaonly config ViewInfo.Instance rovViewInfo =
154 ViewInfo.create({
155 viewMap: [
156 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
157 ['Device', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitDevice', structName: 'DeviceView'}],
158 ]
159 });
160
161 /*!
162 * Assert raised in Timer_create when timer id specified is not supported.
163 */
164 config Assert.Id A_invalidTimer = {
165 msg: "A_invalidTimer: Timer id must be 0-2"
166 };
167
168 /*!
169 * Error raised in Timer_create when timer requested is in use.
170 */
171 config Error.Id E_notAvailable = {
172 msg: "E_notAvailable: Timer not available %d"
173 };
174
175 /*!
176 * Assert raised in Timer_create if an invalid RunMode is requested.
177 */
178 config Assert.Id A_invalidRunMode = {
179 msg: "A_invalidRunMode: Invalid RunMode"
180 };
181
182 /*!
183 * Assert raised when period requested is not supported.
184 */
185 config Assert.Id E_cannotSupport = {
186 msg: "E_cannotSupport: Timer cannot support requested period"
187 };
188
189 /*!
190 * ======== anyMask ========
191 * Available mask to be used when select = Timer_ANY
192 */
193 config UInt anyMask = 0x7;
194
195 /*! Timer enable function type definition. */
196 typedef Void (*TimerEnableFuncPtr)(Int);
197
198 /*! Timer disable function type definition. */
199 typedef Void (*TimerDisableFuncPtr)(Int);
200
201 /*!
202 * ======== enableFunc ========
203 * Pointer to Timer enable callback function
204 *
205 * Timer enable callback function enables the timer.
206 */
207 config TimerEnableFuncPtr enableFunc = null;
208
209 /*!
210 * ======== disableFunc ========
211 * Pointer to Timer disable callback function
212 *
213 * Timer disable callback function disables the timer.
214 */
215 config TimerDisableFuncPtr disableFunc = null;
216
217 instance:
218
219 /*!
220 * ======== emulationModeInit ========
221 * Initial timer emulation mode. Default hard stop.
222 *
223 * Determines timer state at a software breakpoint. If 'free' is 1, the
224 * timer will continue to run, and the value of 'soft' doesn't matter.
225 * When 'free' is 0 and 'soft' is 1, the timer runs down to 0 then stops.
226 * When 'free' is 0 and 'soft' is 0, the timer halts.
227 *
228 * @p(html)
229 * <pre>
230 * FREE SOFT
231 * 0 0 Stop after next timer decrement. (Hard stop)
232 * 0 1 Stop after timer runs down to 0. (Soft stop)
233 * 1 x Continue running the timer.
234 * </pre>
235 */
236 config EmulationMode emulationModeInit = {free: 0, soft: 0};
237
238 /*!
239 * ======== prescale ========
240 * Prescale factor.
241 *
242 * The prescale factor determines the length of a timer tick.
243 * If a prescale of 10 is specified, a timer tick will occur
244 * every 11 cycles.
245 *
246 * If the timer is used as a counter, the prescale factor determines
247 * the period between counts. Otherwise, the prescale factor can be used
248 * to achieve longer timer periods: with a prescale specified, the actual
249 * period is (period * prescale+1).
250 */
251 config UInt16 prescale = 0;
252
253 /*!
254 * ======== hwiParams ========
255 * Parameters for the Hwi object created for the Timer ISR.
256 *
257 * The mask setting for the Hwi object should include SELF to prevent
258 * nested timer interrupts.
259 */
260 config Hwi.Params *hwiParams = null;
261
262 /*!
263 * ======== getCount ========
264 * Returns the number of counts that have passed.
265 *
266 * The 28x timer counts downward from the period to 0, but getCount
267 * subtracts the timer counter value from the period so that getCount
268 * counts upward instead of downward.
269 *
270 * @b(returns) timer counts, counting upward from 0
271 */
272 override UInt32 getCount();
273
274 /*!
275 * ======== setPreScale ========
276 * Set timer prescale value.
277 *
278 * This function sets the value of the prescaler, and will also reload
279 * the timer counter and prescale registers.
280 *
281 * The prescaler decrements with each timer clock source cycle until it
282 * reaches zero, then the timer's count is decremented by one. The
283 * prescaler has the effect of setting the rate of the timer tick.
284 *
285 * @param(preScaler) The value to set the prescale period to.
286 */
287 Void setPrescale(UInt16 preScaler);
288
289 /*!
290 * ======== getPrescale ========
291 * Get timer prescale value.
292 *
293 * This is not the prescale count, but the period of the prescaler.
294 *
295 * @b(returns) prescale value
296 */
297 UInt16 getPrescale();
298
299 /*!
300 * ======== getPrescaleCount ========
301 * Reads timer prescale counter.
302 *
303 * The prescale counter counts down from prescale to 0, but
304 * getPrescaleCount subtracts the counter value from the period so that
305 * this function counts upward instead of downward.
306 *
307 * @b(returns) prescale counter, counting upward from 0
308 */
309 UInt16 getPrescaleCount();
310
311 /*!
312 * ======== reconfig ========
313 * Used to modify timer instances at runtime.
314 *
315 * @param(timerParams) timer Params
316 * @param(tickFxn) functions that runs when timer expires
317 */
318 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
319
320 internal:
321
322 /*!
323 * ======== enableCM ========
324 */
325 Void enableCM(Int id);
326
327 /*!
328 * ======== disableCM ========
329 */
330 Void disableCM(Int id);
331
332 333 334 335
336 Int postInit(Object *timer, Error.Block *eb);
337
338 339 340
341 Void stopAndClear(Object *timer);
342
343 344 345
346 Bool checkOverflow(UInt32 a, UInt32 b);
347
348 /*!
349 * ======== oneShotStub ========
350 * This stub implements oneShot mode by stopping the timer and clearing
351 * the CPU IFR bit.
352 *
353 * @param(arg) The timer object
354 */
355 Void oneShotStub(UArg arg);
356
357 /*!
358 * ======== startupNeeded ========
359 * Flag used to prevent Module_startup and Timer_startup code from being
360 * brought in unnecessarily. Flag is set if there are any static Timer
361 * instances.
362 */
363 config UInt startupNeeded = false;
364
365 config UInt8 intNumDef[3];
366
367 struct Instance_State {
368 Int id;
369 EmulationMode emulationModeInit;
370 ITimer.RunMode runMode;
371 ITimer.StartMode startMode;
372 UInt32 period;
373 ITimer.PeriodType periodType;
374 UInt16 prescale;
375 UInt intNum;
376 UArg arg;
377 Hwi.FuncPtr tickFxn;
378 Types.FreqHz extFreq;
379 Hwi.Handle hwi;
380 }
381
382 struct Module_State {
383 Char availMask;
384 Handle staticTimers[NUM_TIMER_DEVICES]; 385
386 }
387 }