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 String tickFxn[];
217 UArg arg;
218 String hwiHandle;
219 };
220
221 /*! @_nodoc */
222 metaonly struct DeviceView {
223 UInt id;
224 String device;
225 String devAddr;
226 UInt intNum;
227 UInt32 currCount;
228 UInt32 nextCompareCount;
229 UInt32 remainingCount;
230 String state;
231 };
232
233 /*! @_nodoc */
234 metaonly struct ModuleView {
235 String availMask;
236 }
237
238 /*! @_nodoc */
239 @Facet
240 metaonly config ViewInfo.Instance rovViewInfo =
241 ViewInfo.create({
242 viewMap: [
243 [
244 'Basic',
245 {
246 type: ViewInfo.INSTANCE,
247 viewInitFxn: 'viewInitBasic',
248 structName: 'BasicView'
249 }
250 ],
251 [
252 'Device',
253 {
254 type: ViewInfo.INSTANCE,
255 viewInitFxn: 'viewInitDevice',
256 structName: 'DeviceView'
257 }
258 ],
259 [
260 'Module',
261 {
262 type: ViewInfo.MODULE,
263 viewInitFxn: 'viewInitModule',
264 structName: 'ModuleView'
265 }
266 ],
267 ]
268 });
269
270 /*!
271 * ======== E_invalidTimer ========
272 * Error raised when specified timer id is not supported
273 */
274 config Error.Id E_invalidTimer = {
275 msg: "E_invalidTimer: Invalid Timer Id %d"
276 };
277
278 /*!
279 * ======== E_notAvailable ========
280 * Error raised when requested timer is in use
281 */
282 config Error.Id E_notAvailable = {
283 msg: "E_notAvailable: Timer not available %d"
284 };
285
286 /*!
287 * ======== E_cannotSupport ========
288 * Error raised when requested period is not supported
289 */
290 config Error.Id E_cannotSupport = {
291 msg: "E_cannotSupport: Timer cannot support requested period %d"
292 };
293
294 /*!
295 * ======== anyMask ========
296 * Mask of available timers
297 *
298 * This mask is used to identify the timers that can be used when
299 * Timer_create() is called with an id equal to
300 * {@link Timer#ANY Timer_ANY}.
301 */
302 config UInt anyMask = 0x1;
303
304 /*!
305 * ======== funcHookCH1 ========
306 * Optional hook function for processing RTC channel 1 events
307 *
308 * This function will be called when there is a timeout event on
309 * RTC Channel 1. It will be called from hardware interrupt context,
310 * so any API calls from this function must be appropriate for
311 * execution from an ISR.
312 *
313 * Function hooks are only supported with RunMode_DYNAMIC.
314 */
315 config FuncPtr funcHookCH1 = null;
316
317 /*!
318 * ======== funcHookCH2 ========
319 * Optional hook function for processing RTC channel 2 events.
320 *
321 * This function will be called when there is a timeout event on
322 * RTC Channel 2. It will be called from hardware interrupt context,
323 * so any API calls from this function must be appropriate for
324 * execution from an ISR.
325 *
326 * Function hooks are only supported with RunMode_DYNAMIC.
327 */
328 config FuncPtr funcHookCH2 = null;
329
330 /*!
331 * ======== dynamicStub ========
332 * @_nodoc
333 *
334 * @param(arg) Unused.
335 */
336 Void dynamicStub(UArg arg);
337
338 /*!
339 * ======== dynamicMultiStub ========
340 * @_nodoc
341 *
342 * @param(arg) Unused.
343 */
344 Void dynamicMultiStub(UArg arg);
345
346 /*!
347 * ======== periodicStub ========
348 * @_nodoc
349 *
350 * @param(arg) Unused.
351 */
352 Void periodicStub(UArg arg);
353
354 /*!
355 * ======== getCount64 ========
356 * Read the 64-bit timer counter register
357 *
358 * @b(returns) timer counter value
359 */
360 UInt64 getCount64(Object * timer);
361
362 /*!
363 * ======== getExpiredCounts64 ========
364 * Returns expired counts (64-bits) since the last serviced interrupt.
365 *
366 * @b(returns) timer counter value
367 */
368 UInt64 getExpiredCounts64(Object * timer);
369
370 /*!
371 * ======== getHandle ========
372 * @_nodoc
373 * Used by TimestampProvider module to get hold of timer handle used by
374 * Clock.
375 *
376 * @param(id) timer Id.
377 */
378 Handle getHandle(UInt id);
379
380 instance:
381
382 /*! Hwi Params for Hwi Object. Default is null. */
383 config Hwi.Params *hwiParams = null;
384
385 internal:
386
387 /*!
388 * ======== noStartupNeeded ========
389 * Flag used to prevent misc code from being brought in
390 * un-necessarily
391 */
392 config UInt startupNeeded = false;
393
394 395 396 397
398 Void initDevice(Object *timer);
399
400 401 402 403
404 Int postInit(Object *timer, Error.Block *eb);
405
406 407 408 409
410 Void setThreshold(Object *timer, UInt32 next, Bool wrap);
411
412 struct Instance_State {
413 Bool staticInst;
414 Int id;
415 ITimer.StartMode startMode;
416 UInt32 period;
417 UArg arg;
418 Hwi.FuncPtr tickFxn;
419 Types.FreqHz frequency;
420 Hwi.Handle hwi;
421 UInt64 period64;
422 UInt64 savedCurrCount;
423 UInt64 prevThreshold;
424 UInt64 nextThreshold;
425 }
426
427 struct Module_State {
428 UInt availMask;
429 Handle handle;
430 }
431 }