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 package ti.sysbios.family.msp430;
38
39 import xdc.rov.ViewInfo;
40
41 import xdc.runtime.Types;
42 import xdc.runtime.Error;
43
44 import ti.sysbios.interfaces.ITimer;
45
46 /*!
47 * ======== Timer ========
48 * MSP430 Timer Peripherals Manager
49 *
50 * This module manages the timer peripherals available on MSP430 devices
51 * (see {@link ./doc-files/TimerTables.html Timer Mapping Tables} for
52 * supported device information).
53 *
54 * The Timer module supports the timer in 'one shot', 'continuous', and
55 * 'dynamic' modes.
56 *
57 * In 'one shot' mode, a timer function will "fire" (run) when the timer
58 * period expires. In 'one shot' mode this will only happen once.
59 *
60 * In 'continuous' mode, the specified timer function will "fire" every
61 * time the period expires, throughout the lifetime of the program.
62 *
63 * In 'dynamic' mode, the specified timer function will "fire" every
64 * time the period expires. But the period of the timer can be changed
65 * dynamically, to correspond to the next tick interrupt needed from the
66 * timer. This mode is used by the SYS/BIOS
67 * {@link ti.sysbios.knl.Clock Clock} module for implementing
68 * dynamic tick suppression, to reduce the number of interrupts from the
69 * timer to the minimum required for currently scheduled timeouts.
70 *
71 * NOTE: In the current implementation on MSP430 Timers cannot be
72 * created dynamically at runtime by the application. Timers must be
73 * created statically in the application configuration.
74 *
75 * @p(html)
76 * <h3> Calling Context </h3>
77 * <table border="1" cellpadding="3">
78 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
79 * </colgroup>
80 *
81 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
82 * <th> Task </th><th> Main </th><th> Startup </th></tr>
83 * <!-- -->
84 * <tr><td> {@link #getNumTimers} </td><td> Y </td>
85 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
86 * <tr><td> {@link #getStatus} </td><td> Y </td>
87 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
88 * <tr><td> {@link #Params_init} </td><td> N </td>
89 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
90 * <tr><td> {@link #construct} </td><td> N </td>
91 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
92 * <tr><td> {@link #create} </td><td> N </td>
93 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
94 * <tr><td> {@link #delete} </td><td> N </td>
95 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
96 * <tr><td> {@link #destruct} </td><td> N </td>
97 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
98 * <tr><td> {@link #getCount} </td><td> Y </td>
99 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
100 * <tr><td> {@link #getFreq} </td><td> Y </td>
101 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
102 * <tr><td> {@link #getFunc} </td><td> Y </td>
103 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
104 * <tr><td> {@link #getPeriod} </td><td> Y </td>
105 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
106 * <tr><td> {@link #reconfig} </td><td> Y </td>
107 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
108 * <tr><td> {@link #setFunc} </td><td> Y </td>
109 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
110 * <tr><td> {@link #setPeriod} </td><td> Y </td>
111 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
112 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td>
113 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
114 * <tr><td> {@link #start} </td><td> Y </td>
115 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
116 * <tr><td> {@link #stop} </td><td> Y </td>
117 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
118 * <tr><td colspan="6"> Definitions: <br />
119 * <ul>
120 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
121 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
122 * <li> <b>Task</b>: API is callable from a Task thread. </li>
123 * <li> <b>Main</b>: API is callable during any of these phases: </li>
124 * <ul>
125 * <li> In your module startup after this module is started
126 * (e.g. Timer_Module_startupDone() returns TRUE). </li>
127 * <li> During xdc.runtime.Startup.lastFxns. </li>
128 * <li> During main().</li>
129 * <li> During BIOS.startupFxns.</li>
130 * </ul>
131 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
132 * <ul>
133 * <li> During xdc.runtime.Startup.firstFxns.</li>
134 * <li> In your module startup before this module is started
135 * (e.g. Timer_Module_startupDone() returns FALSE).</li>
136 * </ul>
137 * </ul>
138 * </td></tr>
139 *
140 * </table>
141 * @p
142 *
143 * @p(html)
144 * <h3> Timer Mapping Tables </h3>
145 * <p>
146 * The Timer module allows the user to use and configure the various timers
147 * that exist on a particular device. This is achieved by specifying a timer
148 * ID when statically creating the Timer instance.
149 * A convention is used to assign logical IDs to physical timers. ID '0'
150 * corresponds to the first Timer_A peripheral (TA0). ID '1' is assigned to
151 * the next Timer_A (TA1), until there are no more Timer_A peripherals. Then
152 * the next ID is assigned to the first Timer_B peripheral (if present), and
153 * so on.
154 * These tables are provided to show which timers map to which timer IDs.
155 * </p>
156 * {@link ./doc-files/TimerTables.html Timer Mapping Tables}
157 * @p
158 */
159 @InstanceFinalize
160 @InstanceInitError
161 @ModuleStartup
162
163 module Timer inherits ti.sysbios.interfaces.ITimer
164 {
165 /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
166 override metaonly config Bool supportsDynamic = true;
167
168 /*! override defaultMode - use RunMode_DYNAMIC by default */
169 override metaonly config Bool defaultDynamic = true;
170
171
172
173 /*! Lists of input clock sources for timers */
174 enum Source {
175 Source_ACLK, /*! ACLK */
176 Source_SMCLK, /*! SMCLK */
177 Source_EXTERNAL, /*! External clock */
178 Source_EXTERNAL_INVERTED /*! Inverted external clock */
179 };
180
181 /*! Max value of Timer period for PeriodType_COUNTS */
182 const UInt MAX_PERIOD = 0x0000ffff;
183
184 /*! @_nodoc
185 * Min instructions to use in trigger().
186 */
187 const Int MIN_SWEEP_PERIOD = 1;
188
189 /*! Timer Configuration struct.
190 *
191 * @field(source) Timer clock source.
192 */
193 struct Control {
194 UInt source; /*! 0x100=ACLK, 0x200=SMCLK, 0=EXT, 0x300=EXT_INVERT */
195 };
196
197 /*! @_nodoc */
198 @XmlDtd
199 metaonly struct BasicView {
200 Ptr halTimerHandle;
201 String label;
202 UInt id;
203 Control configuration;
204 String startMode;
205 String runMode;
206 UInt period;
207 String periodType;
208 Bool synchronous;
209 UInt intNum;
210 String tickFxn[];
211 UArg arg;
212 UInt frequency;
213 String hwiHandle;
214 };
215
216 /*! @_nodoc */
217 metaonly struct DeviceView {
218 UInt id;
219 String device;
220 String devAddr;
221 UInt intNum;
222 String runMode;
223 UInt period;
224 UInt currCount;
225 UInt remainingCount;
226 UInt prevThreshold;
227 String state;
228 };
229
230 /*! @_nodoc */
231 metaonly struct ModuleView {
232 String availMask;
233 }
234
235 /*! @_nodoc */
236 @Facet
237 metaonly config ViewInfo.Instance rovViewInfo =
238 ViewInfo.create({
239 viewMap: [
240 [
241 'Basic',
242 {
243 type: ViewInfo.INSTANCE,
244 viewInitFxn: 'viewInitBasic',
245 structName: 'BasicView'
246 }
247 ],
248 [
249 'Device',
250 {
251 type: ViewInfo.INSTANCE,
252 viewInitFxn: 'viewInitDevice',
253 structName: 'DeviceView'
254 }
255 ],
256 [
257 'Module',
258 {
259 type: ViewInfo.MODULE,
260 viewInitFxn: 'viewInitModule',
261 structName: 'ModuleView'
262 }
263 ],
264 ]
265 });
266
267 /*!
268 * ======== E_invalidTimer ========
269 * Error raised when specified timer id is not supported
270 */
271 config Error.Id E_invalidTimer = {
272 msg: "E_invalidTimer: Invalid Timer Id %d"
273 };
274
275 /*!
276 * ======== E_notAvailable ========
277 * Error raised when requested timer is in use
278 */
279 config Error.Id E_notAvailable = {
280 msg: "E_notAvailable: Timer not available %d"
281 };
282
283 /*!
284 * ======== E_cannotSupport ========
285 * Error raised when requested period is not supported
286 */
287 config Error.Id E_cannotSupport = {
288 msg: "E_cannotSupport: Timer cannot support requested period %d"
289 };
290
291 /*!
292 * ======== E_runtimeCreate ========
293 * Error raised when dynamic Timer create is attempted
294 */
295 config Error.Id E_runtimeCreate = {
296 msg: "E_runtimeCreate: Runtime Timer create is not supported %d"
297 };
298
299 /*!
300 * ======== anyMask ========
301 * Mask of available timers
302 *
303 * This mask is used to identify the timers that can be used when
304 * Timer_create() is called with an id equal to
305 * {@link Timer#ANY Timer_ANY}.
306 */
307 config UInt anyMask = 0x7;
308
309 /*!
310 * ======== keepAwake ========
311 * Wakeup (enable) CPU when Timer ISR returns
312 *
313 * If set to `true`, all Timer instances keep the CPU awake upon
314 * return from interrupt.
315 */
316 config Bool keepAwake = false;
317
318 /*!
319 * ======== oneShotStub ========
320 * @_nodoc
321 *
322 * @param(arg) Unused.
323 */
324 Void oneShotStub(UArg arg);
325
326 /*!
327 * ======== oneShotNestStub ========
328 * @_nodoc
329 *
330 * @param(arg) Unused.
331 */
332 Void oneShotNestStub(UArg arg);
333
334 /*!
335 * ======== periodicStub ========
336 * @_nodoc
337 *
338 * @param(arg) Unused.
339 */
340 Void periodicStub(UArg arg);
341
342 /*!
343 * ======== periodicNestStub ========
344 * @_nodoc
345 *
346 * @param(arg) Unused.
347 */
348 Void periodicNestStub(UArg arg);
349
350 /*!
351 * ======== getHandle ========
352 * @_nodoc
353 * Used by TimestampProvider module to get hold of timer handle used by
354 * Clock.
355 *
356 * @param(id) timer Id.
357 */
358 Handle getHandle(UInt id);
359
360 instance:
361
362 /*! Hwi Params for Hwi Object. Default is null. */
363 config Hwi.Params *hwiParams = null;
364
365 /*! Clock source input select. Default is ACLK. */
366 config Source clockSource = Source_ACLK;
367
368 /*! Selected clock source is synchronous to CPU clock? Default is false. */
369 config Bool synchronous = false;
370
371 /*! Enable nesting of other interrupts on top of this Timer's ISR? */
372 config Bool nesting = false;
373
374 /*! Previous threshold count value. */
375 config UInt prevThreshold = 0;
376
377 /*! Control register configuration. Default source = ACLK. */
378 config Control controlRegInit = {source: Source_ACLK};
379
380 /*!
381 * ======== reconfig ========
382 * Modify timer instances at runtime
383 *
384 * @param(timerParams) timer Params
385 * @param(tickFxn) function that runs when timer expires.
386 */
387 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
388
389
390 internal:
391
392 /*!
393 * ======== noStartupNeeded ========
394 * Flag used to prevent misc code from being brought in
395 * un-necessarily
396 */
397 config UInt startupNeeded = false;
398
399 /*! Information about timer */
400 struct TimerDevice {
401 UInt intNum;
402 Ptr baseAddr;
403 };
404
405 /*!
406 * ======== numTimerDevices ========
407 * The number of physical timers on the device
408 */
409 config Int numTimerDevices;
410
411 struct Instance_State {
412 Bool staticInst;
413 Int id;
414 UInt controlRegInit;
415 ITimer.RunMode runMode;
416 ITimer.StartMode startMode;
417 UInt period;
418 ITimer.PeriodType periodType;
419 UInt intNum;
420 UArg arg;
421 Hwi.FuncPtr tickFxn;
422 Types.FreqHz frequency;
423 Hwi.Handle hwi;
424 UInt prevThreshold;
425 Bool synchronous;
426 }
427
428 struct Module_State {
429 UInt availMask;
430 TimerDevice device[];
431 Handle handles[];
432 }
433 }
434 435 436 437
438