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.arm.cc26xx;
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 import ti.sysbios.family.arm.m3.Hwi;
46
47 /*!
48 * ======== Timer ========
49 * CC26xx Timer Peripheral Manager
50 *
51 * This Timer module manages the RTC timer peripheral on
52 * CC26XX/CC13XX devices. This Timer operates in a dynamic tick mode
53 * (RunMode_DYNAMIC). Rather than interrupting on every fixed tick period,
54 * the Timer is dynamically reprogrammed to interrupt on the next required
55 * tick (as determined by work that has been scheduled with a future timeout).
56 *
57 * By default, this Timer module is used by the SYS/BIOS
58 * {@link ti.sysbios.knl.Clock Clock} module for implementing timing services
59 * on CC26XX/CC13XX devices. Operating in dynamic mode allows the Clock module
60 * to implement dynamic tick suppression, to reduce the number of interrupts
61 * from the timer, to the minimum required for any scheduled work.
62 *
63 * The RTC peripheral is implemented as a 64-bit counter, with the upper
64 * 32-bits of count representing seconds, and the lower 32-bits representing
65 * sub-seconds. Three timer "channels" are provided for generating time match
66 * interrupt events. The match compare value for each channel is a 32-bit
67 * value, spanning the lower 16-bits of the RTC seconds count, and the upper
68 * 16-bits of the subsecond count. There is a single interrupt line from the
69 * RTC to generate a CPU interrupt, for a match event occurring on any
70 * of these three channels.
71 *
72 * Channel 0 of the RTC is dedicated to use by the Clock module. This Timer
73 * module implementation is therefore responsible for overall management of
74 * the RTC, including resetting and starting the RTC during application boot,
75 * and providing the single interrupt service routine (ISR) for the RTC.
76 *
77 * Channels 1 and 2 of the RTC are not used by the Clock module. These
78 * channels may be available for use by some applications, depending upon the
79 * mix of software components being used. For this purpose, this Timer
80 * module supports sharing of the RTC interrupt, to support usage
81 * of these other channels (in parallel with the usage of Channel 0 by the
82 * Clock module).
83 *
84 * To use one of these other channels the application will need to explicitly
85 * configure an interrupt "hook" function for the channel. In this case, when
86 * an RTC interrupt triggers the ISR will check the status of each channel to
87 * see if the corresponding channel hook function should be called.
88 *
89 * The time match values for Channel 0 will be automatically programmed by
90 * the Clock module. To use Channels 1 (and/or Channel 2), the application
91 * will need to explicitly program the match value for the corresponding
92 * channel, for the desired time for the interrupt. Also, the application
93 * will need to explicitly enable the additional channel, and include it in the
94 * combined event configuration.
95 *
96 * The below snippets show an example of using Channel 1, with Driverlib API
97 * calls to configure an RTC event at 4 seconds after boot.
98 *
99 * First, in the application .cfg file a hook function is defined for
100 * Channel 1:
101 *
102 * @p(code)
103 * var Timer = xdc.module('ti.sysbios.family.arm.cc26xx.Timer');
104 * Timer.funcHookCH1 = "&myHookCH1";
105 * @p
106 *
107 * In main(), Channel 1 is first cleared, a compare (match) value of 4 seconds
108 * is set, the channel is enabled, and is included (along with Channel
109 * 0) in the combined event configuration:
110 *
111 * @p(code)
112 * AONRTCEventClear(AON_RTC_CH1);
113 * AONRTCCompareValueSet(AON_RTC_CH1, 0x40000);
114 * AONRTCChannelEnable(AON_RTC_CH1);
115 * AONRTCCombinedEventConfig(AON_RTC_CH0 | AON_RTC_CH1);
116 * @p
117 *
118 * With the above, myHookCH1() will be called when the RTC reaches a count of
119 * 4 seconds. At that time, a new compare value can be written for the next
120 * interrupt that should occur for Channel 1.
121 *
122 * @p(html)
123 * <h3> Calling Context </h3>
124 * <table border="1" cellpadding="3">
125 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
126 * </colgroup>
127 *
128 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
129 * <th> Task </th><th> Main </th><th> Startup </th></tr>
130 * <!-- -->
131 * <tr><td> {@link #getNumTimers} </td><td> Y </td>
132 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
133 * <tr><td> {@link #getStatus} </td><td> Y </td>
134 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
135 * <tr><td> {@link #Params_init} </td><td> N </td>
136 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
137 * <tr><td> {@link #construct} </td><td> N </td>
138 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
139 * <tr><td> {@link #create} </td><td> N </td>
140 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
141 * <tr><td> {@link #delete} </td><td> N </td>
142 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
143 * <tr><td> {@link #destruct} </td><td> N </td>
144 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
145 * <tr><td> {@link #getCount} </td><td> Y </td>
146 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
147 * <tr><td> {@link #getFreq} </td><td> Y </td>
148 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
149 * <tr><td> {@link #getFunc} </td><td> Y </td>
150 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
151 * <tr><td> {@link #getPeriod} </td><td> Y </td>
152 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
153 * <tr><td> {@link #setFunc} </td><td> Y </td>
154 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
155 * <tr><td> {@link #setPeriod} </td><td> Y </td>
156 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
157 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td>
158 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
159 * <tr><td> {@link #start} </td><td> Y </td>
160 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
161 * <tr><td> {@link #stop} </td><td> Y </td>
162 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
163 * <tr><td colspan="6"> Definitions: <br />
164 * <ul>
165 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
166 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
167 * <li> <b>Task</b>: API is callable from a Task thread. </li>
168 * <li> <b>Main</b>: API is callable during any of these phases: </li>
169 * <ul>
170 * <li> In your module startup after this module is started
171 * (e.g. Timer_Module_startupDone() returns TRUE). </li>
172 * <li> During xdc.runtime.Startup.lastFxns. </li>
173 * <li> During main().</li>
174 * <li> During BIOS.startupFxns.</li>
175 * </ul>
176 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
177 * <ul>
178 * <li> During xdc.runtime.Startup.firstFxns.</li>
179 * <li> In your module startup before this module is started
180 * (e.g. Timer_Module_startupDone() returns FALSE).</li>
181 * </ul>
182 * </ul>
183 * </td></tr>
184 *
185 * </table>
186 * @p
187 */
188 @ModuleStartup
189 @InstanceInitStatic
190
191 module Timer inherits ti.sysbios.interfaces.ITimer
192 {
193 /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
194 override metaonly config Bool supportsDynamic = true;
195
196 /*! override defaultMode - use RunMode_PERIODIC by default */
197 override metaonly config Bool defaultDynamic = true;
198
199
200
201 /*! Max value of Timer period for PeriodType_COUNTS */
202 const UInt MAX_PERIOD = 0xFFFFFFFF;
203
204 /*! @_nodoc
205 * Min instructions to use in trigger().
206 */
207 const Int MIN_SWEEP_PERIOD = 1;
208
209 /*! @_nodoc */
210 @XmlDtd
211 metaonly struct BasicView {
212 Ptr halTimerHandle;
213 String label;
214 UInt id;
215 String startMode;
216 UInt period;
217 String tickFxn[];
218 UArg arg;
219 String hwiHandle;
220 };
221
222 /*! @_nodoc */
223 metaonly struct DeviceView {
224 UInt id;
225 String device;
226 String devAddr;
227 UInt intNum;
228 UInt period;
229 UInt64 period64;
230 UInt currCount;
231 UInt remainingCount;
232 UInt64 prevThreshold;
233 UInt64 nextThreshold;
234 String state;
235 };
236
237 /*! @_nodoc */
238 metaonly struct ModuleView {
239 String availMask;
240 }
241
242 /*! @_nodoc */
243 @Facet
244 metaonly config ViewInfo.Instance rovViewInfo =
245 ViewInfo.create({
246 viewMap: [
247 [
248 'Basic',
249 {
250 type: ViewInfo.INSTANCE,
251 viewInitFxn: 'viewInitBasic',
252 structName: 'BasicView'
253 }
254 ],
255 [
256 'Device',
257 {
258 type: ViewInfo.INSTANCE,
259 viewInitFxn: 'viewInitDevice',
260 structName: 'DeviceView'
261 }
262 ],
263 [
264 'Module',
265 {
266 type: ViewInfo.MODULE,
267 viewInitFxn: 'viewInitModule',
268 structName: 'ModuleView'
269 }
270 ],
271 ]
272 });
273
274 /*!
275 * ======== E_invalidTimer ========
276 * Error raised when specified timer id is not supported
277 */
278 config Error.Id E_invalidTimer = {
279 msg: "E_invalidTimer: Invalid Timer Id %d"
280 };
281
282 /*!
283 * ======== E_notAvailable ========
284 * Error raised when requested timer is in use
285 */
286 config Error.Id E_notAvailable = {
287 msg: "E_notAvailable: Timer not available %d"
288 };
289
290 /*!
291 * ======== E_cannotSupport ========
292 * Error raised when requested period is not supported
293 */
294 config Error.Id E_cannotSupport = {
295 msg: "E_cannotSupport: Timer cannot support requested period %d"
296 };
297
298 /*!
299 * ======== anyMask ========
300 * Mask of available timers
301 *
302 * This mask is used to identify the timers that can be used when
303 * Timer_create() is called with an id equal to
304 * {@link Timer#ANY Timer_ANY}.
305 */
306 config UInt anyMask = 0x1;
307
308 /*!
309 * ======== funcHookCH1 ========
310 * Optional hook function for processing RTC channel 1 events
311 *
312 * This function will be called when there is a timeout event on
313 * RTC Channel 1. It will be called from hardware interrupt context,
314 * so any API calls from this function must be appropriate for
315 * execution from an ISR.
316 *
317 * Function hooks are only supported with RunMode_DYNAMIC.
318 */
319 config FuncPtr funcHookCH1 = null;
320
321 /*!
322 * ======== funcHookCH2 ========
323 * Optional hook function for processing RTC channel 2 events.
324 *
325 * This function will be called when there is a timeout event on
326 * RTC Channel 2. It will be called from hardware interrupt context,
327 * so any API calls from this function must be appropriate for
328 * execution from an ISR.
329 *
330 * Function hooks are only supported with RunMode_DYNAMIC.
331 */
332 config FuncPtr funcHookCH2 = null;
333
334 /*!
335 * ======== dynamicStub ========
336 * @_nodoc
337 *
338 * @param(arg) Unused.
339 */
340 Void dynamicStub(UArg arg);
341
342 /*!
343 * ======== dynamicMultiStub ========
344 * @_nodoc
345 *
346 * @param(arg) Unused.
347 */
348 Void dynamicMultiStub(UArg arg);
349
350 /*!
351 * ======== periodicStub ========
352 * @_nodoc
353 *
354 * @param(arg) Unused.
355 */
356 Void periodicStub(UArg arg);
357
358 /*!
359 * ======== getCount64 ========
360 * Read the 64-bit timer counter register
361 *
362 * @b(returns) timer counter value
363 */
364 UInt64 getCount64(Object * timer);
365
366 /*!
367 * ======== getExpiredCounts64 ========
368 * Returns expired counts (64-bits) since the last serviced interrupt.
369 *
370 * @b(returns) timer counter value
371 */
372 UInt64 getExpiredCounts64(Object * timer);
373
374 /*!
375 * ======== getHandle ========
376 * @_nodoc
377 * Used by TimestampProvider module to get hold of timer handle used by
378 * Clock.
379 *
380 * @param(id) timer Id.
381 */
382 Handle getHandle(UInt id);
383
384 instance:
385
386 /*! Hwi Params for Hwi Object. Default is null. */
387 config Hwi.Params *hwiParams = null;
388
389 internal:
390
391 /*!
392 * ======== noStartupNeeded ========
393 * Flag used to prevent misc code from being brought in
394 * un-necessarily
395 */
396 config UInt startupNeeded = false;
397
398 399 400 401
402 Void initDevice(Object *timer);
403
404 405 406 407
408 Int postInit(Object *timer, Error.Block *eb);
409
410 411 412 413
414 Void setThreshold(Object *timer, UInt32 next, Bool wrap);
415
416 struct Instance_State {
417 Bool staticInst;
418 Int id;
419 ITimer.StartMode startMode;
420 UInt32 period;
421 UArg arg;
422 Hwi.FuncPtr tickFxn;
423 Types.FreqHz frequency;
424 Hwi.Handle hwi;
425 UInt64 period64;
426 UInt64 savedCurrCount;
427 UInt64 prevThreshold;
428 UInt64 nextThreshold;
429 }
430
431 struct Module_State {
432 UInt availMask;
433 Handle handle;
434 }
435 }