1 /******************************************************************************
2 * Filename: timer.c
3 * Revised: 2015-11-16 19:41:47 +0100 (Mon, 16 Nov 2015)
4 * Revision: 45094
5 *
6 * Description: Driver for the General Purpose Timer
7 *
8 * Copyright (c) 2015, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include <driverlib/timer.h>
40
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #if !defined(DOXYGEN)
48 #undef TimerConfigure
49 #define TimerConfigure NOROM_TimerConfigure
50 #undef TimerLevelControl
51 #define TimerLevelControl NOROM_TimerLevelControl
52 #undef TimerStallControl
53 #define TimerStallControl NOROM_TimerStallControl
54 #undef TimerWaitOnTriggerControl
55 #define TimerWaitOnTriggerControl NOROM_TimerWaitOnTriggerControl
56 #undef TimerIntRegister
57 #define TimerIntRegister NOROM_TimerIntRegister
58 #undef TimerIntUnregister
59 #define TimerIntUnregister NOROM_TimerIntUnregister
60 #undef TimerMatchUpdateMode
61 #define TimerMatchUpdateMode NOROM_TimerMatchUpdateMode
62 #undef TimerIntervalLoadMode
63 #define TimerIntervalLoadMode NOROM_TimerIntervalLoadMode
64 #endif
65
66 //*****************************************************************************
67 //
68 //! \brief Gets the timer interrupt number.
69 //!
70 //! Given a timer base address, this function returns the corresponding
71 //! interrupt number.
72 //!
73 //! \param ui32Base is the base address of the timer module.
74 //!
75 //! \return Returns a timer interrupt number, or -1 if \c ui32Base is invalid.
76 //
77 //*****************************************************************************
78 static uint32_t
TimerIntNumberGet(uint32_t ui32Base)79 TimerIntNumberGet(uint32_t ui32Base)
80 {
81 uint32_t ui32Int;
82
83 //
84 // Loop through the table that maps timer base addresses to interrupt
85 // numbers.
86 //
87 switch(ui32Base)
88 {
89 case GPT0_BASE :
90 ui32Int = INT_GPT0A;
91 break;
92 case GPT1_BASE :
93 ui32Int = INT_GPT1A;
94 break;
95 case GPT2_BASE :
96 ui32Int = INT_GPT2A;
97 break;
98 case GPT3_BASE :
99 ui32Int = INT_GPT3A;
100 break;
101 default :
102 ui32Int = 0x0;
103 }
104
105 //
106 // Return the interrupt number or (-1) if not base address is not matched.
107 //
108 return (ui32Int);
109 }
110
111 //*****************************************************************************
112 //
113 //! Configures the timer(s)
114 //
115 //*****************************************************************************
116 void
TimerConfigure(uint32_t ui32Base,uint32_t ui32Config)117 TimerConfigure(uint32_t ui32Base, uint32_t ui32Config)
118 {
119 //
120 // Check the arguments.
121 //
122 ASSERT(TimerBaseValid(ui32Base));
123 ASSERT((ui32Config == TIMER_CFG_ONE_SHOT) ||
124 (ui32Config == TIMER_CFG_ONE_SHOT_UP) ||
125 (ui32Config == TIMER_CFG_PERIODIC) ||
126 (ui32Config == TIMER_CFG_PERIODIC_UP) ||
127 ((ui32Config & 0xFF000000) == TIMER_CFG_SPLIT_PAIR));
128 ASSERT(((ui32Config & 0xFF000000) != TIMER_CFG_SPLIT_PAIR) ||
129 ((((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT) ||
130 ((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT_UP) ||
131 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC) ||
132 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC_UP) ||
133 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT) ||
134 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT_UP) ||
135 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME) ||
136 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME_UP) ||
137 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PWM)) &&
138 (((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT) ||
139 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT_UP) ||
140 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC) ||
141 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC_UP) ||
142 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT) ||
143 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT_UP) ||
144 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME) ||
145 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME_UP) ||
146 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PWM))));
147
148 //
149 // Disable the timers.
150 //
151 HWREG(ui32Base + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN);
152
153 //
154 // Set the global timer configuration.
155 //
156 HWREG(ui32Base + GPT_O_CFG) = ui32Config >> 24;
157
158 //
159 // Set the configuration of the A and B timers. Note that the B timer
160 // configuration is ignored by the hardware in 32-bit modes.
161 //
162 HWREG(ui32Base + GPT_O_TAMR) = (ui32Config & 0xFF) | GPT_TAMR_TAPWMIE;
163 HWREG(ui32Base + GPT_O_TBMR) =
164 ((ui32Config >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
165 }
166
167 //*****************************************************************************
168 //
169 //! Controls the output level
170 //
171 //*****************************************************************************
172 void
TimerLevelControl(uint32_t ui32Base,uint32_t ui32Timer,bool bInvert)173 TimerLevelControl(uint32_t ui32Base, uint32_t ui32Timer, bool bInvert)
174 {
175 //
176 // Check the arguments.
177 //
178 ASSERT(TimerBaseValid(ui32Base));
179 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
180 (ui32Timer == TIMER_BOTH));
181
182 //
183 // Set the output levels as requested.
184 //
185 ui32Timer &= GPT_CTL_TAPWML | GPT_CTL_TBPWML;
186 HWREG(ui32Base + GPT_O_CTL) = (bInvert ?
187 (HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
188 (HWREG(ui32Base + GPT_O_CTL) &
189 ~(ui32Timer)));
190 }
191
192 //*****************************************************************************
193 //
194 //! Controls the stall handling
195 //
196 //*****************************************************************************
197 void
TimerStallControl(uint32_t ui32Base,uint32_t ui32Timer,bool bStall)198 TimerStallControl(uint32_t ui32Base, uint32_t ui32Timer, bool bStall)
199 {
200 //
201 // Check the arguments.
202 //
203 ASSERT(TimerBaseValid(ui32Base));
204 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
205 (ui32Timer == TIMER_BOTH));
206
207 //
208 // Set the stall mode.
209 //
210 ui32Timer &= GPT_CTL_TASTALL | GPT_CTL_TBSTALL;
211 HWREG(ui32Base + GPT_O_CTL) = (bStall ?
212 (HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
213 (HWREG(ui32Base + GPT_O_CTL) & ~(ui32Timer)));
214 }
215
216 //*****************************************************************************
217 //
218 //! Controls the wait on trigger handling
219 //
220 //*****************************************************************************
221 void
TimerWaitOnTriggerControl(uint32_t ui32Base,uint32_t ui32Timer,bool bWait)222 TimerWaitOnTriggerControl(uint32_t ui32Base, uint32_t ui32Timer, bool bWait)
223 {
224 //
225 // Check the arguments.
226 //
227 ASSERT(TimerBaseValid(ui32Base));
228 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
229 (ui32Timer == TIMER_BOTH));
230
231 //
232 // Set the wait on trigger mode for timer A.
233 //
234 if(ui32Timer & TIMER_A)
235 {
236 if(bWait)
237 {
238 HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAWOT;
239 }
240 else
241 {
242 HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAWOT);
243 }
244 }
245
246 //
247 // Set the wait on trigger mode for timer B.
248 //
249 if(ui32Timer & TIMER_B)
250 {
251 if(bWait)
252 {
253 HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBWOT;
254 }
255 else
256 {
257 HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBWOT);
258 }
259 }
260 }
261
262 //*****************************************************************************
263 //
264 //! Registers an interrupt handler for the timer interrupt
265 //
266 //*****************************************************************************
267 void
TimerIntRegister(uint32_t ui32Base,uint32_t ui32Timer,void (* pfnHandler)(void))268 TimerIntRegister(uint32_t ui32Base, uint32_t ui32Timer, void (*pfnHandler)(void))
269 {
270 uint32_t ui32Int;
271
272 //
273 // Check the arguments.
274 //
275 ASSERT(TimerBaseValid(ui32Base));
276 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
277 (ui32Timer == TIMER_BOTH));
278
279 //
280 // Get the interrupt number for this timer module.
281 //
282 ui32Int = TimerIntNumberGet(ui32Base);
283
284 //
285 // Register an interrupt handler for timer A if requested.
286 //
287 if(ui32Timer & TIMER_A)
288 {
289 //
290 // Register the interrupt handler.
291 //
292 IntRegister(ui32Int, pfnHandler);
293
294 //
295 // Enable the interrupt.
296 //
297 IntEnable(ui32Int);
298 }
299
300 //
301 // Register an interrupt handler for timer B if requested.
302 //
303 if(ui32Timer & TIMER_B)
304 {
305 //
306 // Register the interrupt handler.
307 //
308 IntRegister(ui32Int + 1, pfnHandler);
309
310 //
311 // Enable the interrupt.
312 //
313 IntEnable(ui32Int + 1);
314 }
315 }
316
317 //*****************************************************************************
318 //
319 //! Unregisters an interrupt handler for the timer interrupt
320 //
321 //*****************************************************************************
322 void
TimerIntUnregister(uint32_t ui32Base,uint32_t ui32Timer)323 TimerIntUnregister(uint32_t ui32Base, uint32_t ui32Timer)
324 {
325 uint32_t ui32Int;
326
327 //
328 // Check the arguments.
329 //
330 ASSERT(TimerBaseValid(ui32Base));
331 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
332 (ui32Timer == TIMER_BOTH));
333
334 //
335 // Get the interrupt number for this timer module.
336 //
337 ui32Int = TimerIntNumberGet(ui32Base);
338
339 //
340 // Unregister the interrupt handler for timer A if requested.
341 //
342 if(ui32Timer & TIMER_A)
343 {
344 //
345 // Disable the interrupt.
346 //
347 IntDisable(ui32Int);
348
349 //
350 // Unregister the interrupt handler.
351 //
352 IntUnregister(ui32Int);
353 }
354
355 //
356 // Unregister the interrupt handler for timer B if requested.
357 //
358 if(ui32Timer & TIMER_B)
359 {
360 //
361 // Disable the interrupt.
362 //
363 IntDisable(ui32Int + 1);
364
365 //
366 // Unregister the interrupt handler.
367 //
368 IntUnregister(ui32Int + 1);
369 }
370 }
371
372 //*****************************************************************************
373 //
374 // Sets the Match Register Update mode
375 //
376 //*****************************************************************************
377 void
TimerMatchUpdateMode(uint32_t ui32Base,uint32_t ui32Timer,uint32_t ui32Mode)378 TimerMatchUpdateMode(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Mode)
379 {
380 // Check the arguments
381 ASSERT(TimerBaseValid(ui32Base));
382 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) || (ui32Timer == TIMER_BOTH));
383 ASSERT((ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE) || (ui32Mode == TIMER_MATCHUPDATE_TIMEOUT));
384
385 // Set mode for timer A
386 if(ui32Timer & TIMER_A)
387 {
388 if(ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE)
389 {
390 HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAMRSU);
391 }
392 else
393 {
394 HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAMRSU;
395 }
396 }
397
398 // Set mode for timer B
399 if(ui32Timer & TIMER_B)
400 {
401 if(ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE)
402 {
403 HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBMRSU);
404 }
405 else
406 {
407 HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBMRSU;
408 }
409 }
410 }
411
412 //*****************************************************************************
413 //
414 // Sets the Interval Load mode
415 //
416 //*****************************************************************************
417 void
TimerIntervalLoadMode(uint32_t ui32Base,uint32_t ui32Timer,uint32_t ui32Mode)418 TimerIntervalLoadMode(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Mode)
419 {
420 // Check the arguments
421 ASSERT(TimerBaseValid(ui32Base));
422 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) || (ui32Timer == TIMER_BOTH));
423 ASSERT((ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE) || (ui32Mode == TIMER_INTERVALLOAD_TIMEOUT));
424
425 // Set mode for timer A
426 if(ui32Timer & TIMER_A)
427 {
428 if(ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE)
429 {
430 HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAILD);
431 }
432 else
433 {
434 HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAILD;
435 }
436 }
437
438 // Set mode for timer B
439 if(ui32Timer & TIMER_B)
440 {
441 if(ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE)
442 {
443 HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBILD);
444 }
445 else
446 {
447 HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBILD;
448 }
449 }
450 }
451