1 /******************************************************************************
2 * Filename: timer.c
3 * Revised: 2017-04-26 18:27:45 +0200 (Wed, 26 Apr 2017)
4 * Revision: 48852
5 *
6 * Description: Driver for the General Purpose Timer
7 *
8 * Copyright (c) 2015 - 2020, 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 "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 // Loop through the table that maps timer base addresses to interrupt
84 // numbers.
85 switch(ui32Base)
86 {
87 case GPT0_BASE :
88 ui32Int = INT_GPT0A;
89 break;
90 case GPT1_BASE :
91 ui32Int = INT_GPT1A;
92 break;
93 case GPT2_BASE :
94 ui32Int = INT_GPT2A;
95 break;
96 case GPT3_BASE :
97 ui32Int = INT_GPT3A;
98 break;
99 default :
100 ui32Int = 0x0;
101 }
102
103 // Return the interrupt number or (-1) if not base address is not matched.
104 return (ui32Int);
105 }
106
107 //*****************************************************************************
108 //
109 // Configures the timer(s)
110 //
111 //*****************************************************************************
112 void
TimerConfigure(uint32_t ui32Base,uint32_t ui32Config)113 TimerConfigure(uint32_t ui32Base, uint32_t ui32Config)
114 {
115 // Check the arguments.
116 ASSERT(TimerBaseValid(ui32Base));
117 ASSERT((ui32Config == TIMER_CFG_ONE_SHOT) ||
118 (ui32Config == TIMER_CFG_ONE_SHOT_UP) ||
119 (ui32Config == TIMER_CFG_PERIODIC) ||
120 (ui32Config == TIMER_CFG_PERIODIC_UP) ||
121 ((ui32Config & 0xFF000000) == TIMER_CFG_SPLIT_PAIR));
122 ASSERT(((ui32Config & 0xFF000000) != TIMER_CFG_SPLIT_PAIR) ||
123 ((((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT) ||
124 ((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT_UP) ||
125 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC) ||
126 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC_UP) ||
127 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT) ||
128 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT_UP) ||
129 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME) ||
130 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME_UP) ||
131 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PWM)) &&
132 (((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT) ||
133 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT_UP) ||
134 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC) ||
135 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC_UP) ||
136 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT) ||
137 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT_UP) ||
138 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME) ||
139 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME_UP) ||
140 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PWM))));
141
142 // Disable the timers.
143 HWREG(ui32Base + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN);
144
145 // Set the global timer configuration.
146 HWREG(ui32Base + GPT_O_CFG) = ui32Config >> 24;
147
148 // Set the configuration of the A and B timers. Note that the B timer
149 // configuration is ignored by the hardware in 32-bit modes.
150 HWREG(ui32Base + GPT_O_TAMR) = (ui32Config & 0xFF) | GPT_TAMR_TAPWMIE;
151 HWREG(ui32Base + GPT_O_TBMR) =
152 ((ui32Config >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
153 }
154
155 //*****************************************************************************
156 //
157 // Controls the output level
158 //
159 //*****************************************************************************
160 void
TimerLevelControl(uint32_t ui32Base,uint32_t ui32Timer,bool bInvert)161 TimerLevelControl(uint32_t ui32Base, uint32_t ui32Timer, bool bInvert)
162 {
163 // Check the arguments.
164 ASSERT(TimerBaseValid(ui32Base));
165 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
166 (ui32Timer == TIMER_BOTH));
167
168 // Set the output levels as requested.
169 ui32Timer &= GPT_CTL_TAPWML | GPT_CTL_TBPWML;
170 HWREG(ui32Base + GPT_O_CTL) = (bInvert ?
171 (HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
172 (HWREG(ui32Base + GPT_O_CTL) &
173 ~(ui32Timer)));
174 }
175
176 //*****************************************************************************
177 //
178 // Controls the stall handling
179 //
180 //*****************************************************************************
181 void
TimerStallControl(uint32_t ui32Base,uint32_t ui32Timer,bool bStall)182 TimerStallControl(uint32_t ui32Base, uint32_t ui32Timer, bool bStall)
183 {
184 // Check the arguments.
185 ASSERT(TimerBaseValid(ui32Base));
186 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
187 (ui32Timer == TIMER_BOTH));
188
189 // Set the stall mode.
190 ui32Timer &= GPT_CTL_TASTALL | GPT_CTL_TBSTALL;
191 HWREG(ui32Base + GPT_O_CTL) = (bStall ?
192 (HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
193 (HWREG(ui32Base + GPT_O_CTL) & ~(ui32Timer)));
194 }
195
196 //*****************************************************************************
197 //
198 // Controls the wait on trigger handling
199 //
200 //*****************************************************************************
201 void
TimerWaitOnTriggerControl(uint32_t ui32Base,uint32_t ui32Timer,bool bWait)202 TimerWaitOnTriggerControl(uint32_t ui32Base, uint32_t ui32Timer, bool bWait)
203 {
204 // Check the arguments.
205 ASSERT(TimerBaseValid(ui32Base));
206 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
207 (ui32Timer == TIMER_BOTH));
208
209 // Set the wait on trigger mode for timer A.
210 if(ui32Timer & TIMER_A)
211 {
212 if(bWait)
213 {
214 HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAWOT;
215 }
216 else
217 {
218 HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAWOT);
219 }
220 }
221
222 // Set the wait on trigger mode for timer B.
223 if(ui32Timer & TIMER_B)
224 {
225 if(bWait)
226 {
227 HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBWOT;
228 }
229 else
230 {
231 HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBWOT);
232 }
233 }
234 }
235
236 //*****************************************************************************
237 //
238 // Registers an interrupt handler for the timer interrupt
239 //
240 //*****************************************************************************
241 void
TimerIntRegister(uint32_t ui32Base,uint32_t ui32Timer,void (* pfnHandler)(void))242 TimerIntRegister(uint32_t ui32Base, uint32_t ui32Timer, void (*pfnHandler)(void))
243 {
244 uint32_t ui32Int;
245
246 // Check the arguments.
247 ASSERT(TimerBaseValid(ui32Base));
248 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
249 (ui32Timer == TIMER_BOTH));
250
251 // Get the interrupt number for this timer module.
252 ui32Int = TimerIntNumberGet(ui32Base);
253
254 // Register an interrupt handler for timer A if requested.
255 if(ui32Timer & TIMER_A)
256 {
257 // Register the interrupt handler.
258 IntRegister(ui32Int, pfnHandler);
259
260 // Enable the interrupt.
261 IntEnable(ui32Int);
262 }
263
264 // Register an interrupt handler for timer B if requested.
265 if(ui32Timer & TIMER_B)
266 {
267 // Register the interrupt handler.
268 IntRegister(ui32Int + 1, pfnHandler);
269
270 // Enable the interrupt.
271 IntEnable(ui32Int + 1);
272 }
273 }
274
275 //*****************************************************************************
276 //
277 // Unregisters an interrupt handler for the timer interrupt
278 //
279 //*****************************************************************************
280 void
TimerIntUnregister(uint32_t ui32Base,uint32_t ui32Timer)281 TimerIntUnregister(uint32_t ui32Base, uint32_t ui32Timer)
282 {
283 uint32_t ui32Int;
284
285 // Check the arguments.
286 ASSERT(TimerBaseValid(ui32Base));
287 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
288 (ui32Timer == TIMER_BOTH));
289
290 // Get the interrupt number for this timer module.
291 ui32Int = TimerIntNumberGet(ui32Base);
292
293 // Unregister the interrupt handler for timer A if requested.
294 if(ui32Timer & TIMER_A)
295 {
296 // Disable the interrupt.
297 IntDisable(ui32Int);
298
299 // Unregister the interrupt handler.
300 IntUnregister(ui32Int);
301 }
302
303 // Unregister the interrupt handler for timer B if requested.
304 if(ui32Timer & TIMER_B)
305 {
306 // Disable the interrupt.
307 IntDisable(ui32Int + 1);
308
309 // Unregister the interrupt handler.
310 IntUnregister(ui32Int + 1);
311 }
312 }
313
314 //*****************************************************************************
315 //
316 // Sets the Match Register Update mode
317 //
318 //*****************************************************************************
319 void
TimerMatchUpdateMode(uint32_t ui32Base,uint32_t ui32Timer,uint32_t ui32Mode)320 TimerMatchUpdateMode(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Mode)
321 {
322 // Check the arguments
323 ASSERT(TimerBaseValid(ui32Base));
324 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) || (ui32Timer == TIMER_BOTH));
325 ASSERT((ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE) || (ui32Mode == TIMER_MATCHUPDATE_TIMEOUT));
326
327 // Set mode for timer A
328 if(ui32Timer & TIMER_A)
329 {
330 if(ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE)
331 {
332 HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAMRSU);
333 }
334 else
335 {
336 HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAMRSU;
337 }
338 }
339
340 // Set mode for timer B
341 if(ui32Timer & TIMER_B)
342 {
343 if(ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE)
344 {
345 HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBMRSU);
346 }
347 else
348 {
349 HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBMRSU;
350 }
351 }
352 }
353
354 //*****************************************************************************
355 //
356 // Sets the Interval Load mode
357 //
358 //*****************************************************************************
359 void
TimerIntervalLoadMode(uint32_t ui32Base,uint32_t ui32Timer,uint32_t ui32Mode)360 TimerIntervalLoadMode(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Mode)
361 {
362 // Check the arguments
363 ASSERT(TimerBaseValid(ui32Base));
364 ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) || (ui32Timer == TIMER_BOTH));
365 ASSERT((ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE) || (ui32Mode == TIMER_INTERVALLOAD_TIMEOUT));
366
367 // Set mode for timer A
368 if(ui32Timer & TIMER_A)
369 {
370 if(ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE)
371 {
372 HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAILD);
373 }
374 else
375 {
376 HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAILD;
377 }
378 }
379
380 // Set mode for timer B
381 if(ui32Timer & TIMER_B)
382 {
383 if(ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE)
384 {
385 HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBILD);
386 }
387 else
388 {
389 HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBILD;
390 }
391 }
392 }
393