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(s). Note that if a
94 * hook function is configured for Channel 1 or Channel 2, the corresponding
95 * events will be configured automatically when Channel 0 is started. In
96 * other words, there is no need for the application to explicitly configure
97 * events for Channel 1 or Channel 2 by calling AONRTCCombinedEventConfig().
98 *
99 * The below snippets show an example of using Channel 1, with Driverlib API
100 * calls to configure an RTC event at 4 seconds after boot.
101 *
102 * First, in the application .cfg file a hook function is defined for
103 * Channel 1:
104 *
105 * @p(code)
106 * var Timer = xdc.module('ti.sysbios.family.arm.cc26xx.Timer');
107 * Timer.funcHookCH1 = "&myHookCH1";
108 * @p
109 *
110 * In main(), Channel 1 is first cleared, a compare (match) value of 4 seconds
111 * is set, the channel is enabled:
112 *
113 * @p(code)
114 * AONRTCEventClear(AON_RTC_CH1);
115 * AONRTCCompareValueSet(AON_RTC_CH1, 0x40000);
116 * AONRTCChannelEnable(AON_RTC_CH1);
117 * @p
118 *
119 * With the above, myHookCH1() will be called when the RTC reaches a count of
120 * 4 seconds. At that time, a new compare value can be written for the next
121 * interrupt that should occur for Channel 1.
122 *
123 * @p(html)
124 * <h3> Calling Context </h3>
125 * <table border="1" cellpadding="3">
126 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
127 * </colgroup>
128 *
129 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
130 * <th> Task </th><th> Main </th><th> Startup </th></tr>
131 * <!-- -->
132 * <tr><td> {@link #getNumTimers} </td><td> Y </td>
133 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
134 * <tr><td> {@link #getStatus} </td><td> Y </td>
135 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
136 * <tr><td> {@link #Params_init} </td><td> N </td>
137 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
138 * <tr><td> {@link #construct} </td><td> N </td>
139 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
140 * <tr><td> {@link #create} </td><td> N </td>
141 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
142 * <tr><td> {@link #delete} </td><td> N </td>
143 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
144 * <tr><td> {@link #destruct} </td><td> N </td>
145 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
146 * <tr><td> {@link #getCount} </td><td> Y </td>
147 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
148 * <tr><td> {@link #getFreq} </td><td> Y </td>
149 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
150 * <tr><td> {@link #getFunc} </td><td> Y </td>
151 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
152 * <tr><td> {@link #getPeriod} </td><td> Y </td>
153 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
154 * <tr><td> {@link #setFunc} </td><td> Y </td>
155 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
156 * <tr><td> {@link #setPeriod} </td><td> Y </td>
157 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
158 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td>
159 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
160 * <tr><td> {@link #start} </td><td> Y </td>
161 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
162 * <tr><td> {@link #stop} </td><td> Y </td>
163 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
164 * <tr><td colspan="6"> Definitions: <br />
165 * <ul>
166 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
167 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
168 * <li> <b>Task</b>: API is callable from a Task thread. </li>
169 * <li> <b>Main</b>: API is callable during any of these phases: </li>
170 * <ul>
171 * <li> In your module startup after this module is started
172 * (e.g. Timer_Module_startupDone() returns TRUE). </li>
173 * <li> During xdc.runtime.Startup.lastFxns. </li>
174 * <li> During main().</li>
175 * <li> During BIOS.startupFxns.</li>
176 * </ul>
177 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
178 * <ul>
179 * <li> During xdc.runtime.Startup.firstFxns.</li>
180 * <li> In your module startup before this module is started
181 * (e.g. Timer_Module_startupDone() returns FALSE).</li>
182 * </ul>
183 * </ul>
184 * </td></tr>
185 *
186 * </table>
187 * @p
188 */
189 @ModuleStartup
190 @InstanceInitStatic
191
192 module Timer inherits ti.sysbios.interfaces.ITimer
193 {
194 /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
195 override metaonly config Bool supportsDynamic = true;
196
197 /*! override defaultMode - use RunMode_PERIODIC by default */
198 override metaonly config Bool defaultDynamic = true;
199
200
201
202 /*! Max value of Timer period for PeriodType_COUNTS */
203 const UInt MAX_PERIOD = 0xFFFFFFFF;
204
205 /*! @_nodoc
206 * Min instructions to use in trigger().
207 */
208 const Int MIN_SWEEP_PERIOD = 1;
209
210 /*! @_nodoc */
211 @XmlDtd
212 metaonly struct BasicView {
213 Ptr halTimerHandle;
214 String label;
215 UInt id;
216 String startMode;
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 UInt32 currCount;
229 UInt32 nextCompareCount;
230 UInt32 remainingCount;
231 String state;
232 };
233
234 /*! @_nodoc */
235 metaonly struct ModuleView {
236 String availMask;
237 }
238
239 /*! @_nodoc */
240 @Facet
241 metaonly config ViewInfo.Instance rovViewInfo =
242 ViewInfo.create({
243 viewMap: [
244 [
245 'Basic',
246 {
247 type: ViewInfo.INSTANCE,
248 viewInitFxn: 'viewInitBasic',
249 structName: 'BasicView'
250 }
251 ],
252 [
253 'Device',
254 {
255 type: ViewInfo.INSTANCE,
256 viewInitFxn: 'viewInitDevice',
257 structName: 'DeviceView'
258 }
259 ],
260 [
261 'Module',
262 {
263 type: ViewInfo.MODULE,
264 viewInitFxn: 'viewInitModule',
265 structName: 'ModuleView'
266 }
267 ],
268 ]
269 });
270
271 /*!
272 * ======== E_invalidTimer ========
273 * Error raised when specified timer id is not supported
274 */
275 config Error.Id E_invalidTimer = {
276 msg: "E_invalidTimer: Invalid Timer Id %d"
277 };
278
279 /*!
280 * ======== E_notAvailable ========
281 * Error raised when requested timer is in use
282 */
283 config Error.Id E_notAvailable = {
284 msg: "E_notAvailable: Timer not available %d"
285 };
286
287 /*!
288 * ======== E_cannotSupport ========
289 * Error raised when requested period is not supported
290 */
291 config Error.Id E_cannotSupport = {
292 msg: "E_cannotSupport: Timer cannot support requested period %d"
293 };
294
295 /*!
296 * ======== anyMask ========
297 * Mask of available timers
298 *
299 * This mask is used to identify the timers that can be used when
300 * Timer_create() is called with an id equal to
301 * {@link Timer#ANY Timer_ANY}.
302 */
303 config UInt anyMask = 0x1;
304
305 /*!
306 * ======== funcHookCH1 ========
307 * Optional hook function for processing RTC channel 1 events
308 *
309 * This function will be called when there is a timeout event on
310 * RTC Channel 1. It will be called from hardware interrupt context,
311 * so any API calls from this function must be appropriate for
312 * execution from an ISR.
313 *
314 * Function hooks are only supported with RunMode_DYNAMIC.
315 */
316 config FuncPtr funcHookCH1 = null;
317
318 /*!
319 * ======== funcHookCH2 ========
320 * Optional hook function for processing RTC channel 2 events.
321 *
322 * This function will be called when there is a timeout event on
323 * RTC Channel 2. It will be called from hardware interrupt context,
324 * so any API calls from this function must be appropriate for
325 * execution from an ISR.
326 *
327 * Function hooks are only supported with RunMode_DYNAMIC.
328 */
329 config FuncPtr funcHookCH2 = null;
330
331 /*!
332 * ======== dynamicStub ========
333 * @_nodoc
334 *
335 * @param(arg) Unused.
336 */
337 Void dynamicStub(UArg arg);
338
339 /*!
340 * ======== dynamicMultiStub ========
341 * @_nodoc
342 *
343 * @param(arg) Unused.
344 */
345 Void dynamicMultiStub(UArg arg);
346
347 /*!
348 * ======== periodicStub ========
349 * @_nodoc
350 *
351 * @param(arg) Unused.
352 */
353 Void periodicStub(UArg arg);
354
355 /*!
356 * ======== getCount64 ========
357 * Read the 64-bit timer counter register
358 *
359 * @b(returns) timer counter value
360 */
361 UInt64 getCount64(Object * timer);
362
363 /*!
364 * ======== getExpiredCounts64 ========
365 * Returns expired counts (64-bits) since the last serviced interrupt.
366 *
367 * @b(returns) timer counter value
368 */
369 UInt64 getExpiredCounts64(Object * timer);
370
371 /*!
372 * ======== getHandle ========
373 * @_nodoc
374 * Used by TimestampProvider module to get hold of timer handle used by
375 * Clock.
376 *
377 * @param(id) timer Id.
378 */
379 Handle getHandle(UInt id);
380
381 instance:
382
383 /*! Hwi Params for Hwi Object. Default is null. */
384 config Hwi.Params *hwiParams = null;
385
386 internal:
387
388 /*!
389 * ======== noStartupNeeded ========
390 * Flag used to prevent misc code from being brought in
391 * un-necessarily
392 */
393 config UInt startupNeeded = false;
394
395 396 397 398
399 Void initDevice(Object *timer);
400
401 402 403 404
405 Int postInit(Object *timer, Error.Block *eb);
406
407 408 409 410
411 Void setThreshold(Object *timer, UInt32 next, Bool wrap);
412
413 struct Instance_State {
414 Bool staticInst;
415 Int id;
416 ITimer.StartMode startMode;
417 UInt32 period;
418 UArg arg;
419 Hwi.FuncPtr tickFxn;
420 Types.FreqHz frequency;
421 Hwi.Handle hwi;
422 UInt64 period64;
423 UInt64 savedCurrCount;
424 UInt64 prevThreshold;
425 UInt64 nextThreshold;
426 }
427
428 struct Module_State {
429 UInt availMask;
430 Handle handle;
431 }
432 }