1 | /* |
2 | * Copyright 2017-2020 NXP |
3 | * All rights reserved. |
4 | * |
5 | * SPDX-License-Identifier: BSD-3-Clause |
6 | */ |
7 | |
8 | #include "fsl_qtmr.h" |
9 | |
10 | /* Component ID definition, used by tools. */ |
11 | #ifndef FSL_COMPONENT_ID |
12 | #define FSL_COMPONENT_ID "platform.drivers.qtmr" |
13 | #endif |
14 | |
15 | /******************************************************************************* |
16 | * Prototypes |
17 | ******************************************************************************/ |
18 | /*! |
19 | * @brief Gets the instance from the base address to be used to gate or ungate the module clock |
20 | * |
21 | * @param base Quad Timer peripheral base address |
22 | * |
23 | * @return The Quad Timer instance |
24 | */ |
25 | static uint32_t QTMR_GetInstance(TMR_Type *base); |
26 | |
27 | /******************************************************************************* |
28 | * Variables |
29 | ******************************************************************************/ |
30 | /*! @brief Pointers to Quad Timer bases for each instance. */ |
31 | static TMR_Type *const s_qtmrBases[] = TMR_BASE_PTRS; |
32 | |
33 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
34 | /*! @brief Pointers to Quad Timer clocks for each instance. */ |
35 | static const clock_ip_name_t s_qtmrClocks[] = TMR_CLOCKS; |
36 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
37 | |
38 | /******************************************************************************* |
39 | * Code |
40 | ******************************************************************************/ |
41 | static uint32_t QTMR_GetInstance(TMR_Type *base) |
42 | { |
43 | uint32_t instance; |
44 | |
45 | /* Find the instance index from base address mappings. */ |
46 | for (instance = 0; instance < ARRAY_SIZE(s_qtmrBases); instance++) |
47 | { |
48 | if (s_qtmrBases[instance] == base) |
49 | { |
50 | break; |
51 | } |
52 | } |
53 | |
54 | assert(instance < ARRAY_SIZE(s_qtmrBases)); |
55 | |
56 | return instance; |
57 | } |
58 | |
59 | /*! |
60 | * brief Ungates the Quad Timer clock and configures the peripheral for basic operation. |
61 | * |
62 | * note This API should be called at the beginning of the application using the Quad Timer driver. |
63 | * |
64 | * param base Quad Timer peripheral base address |
65 | * param channel Quad Timer channel number |
66 | * param config Pointer to user's Quad Timer config structure |
67 | */ |
68 | void QTMR_Init(TMR_Type *base, qtmr_channel_selection_t channel, const qtmr_config_t *config) |
69 | { |
70 | assert(NULL != config); |
71 | |
72 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
73 | /* Enable the module clock */ |
74 | CLOCK_EnableClock(s_qtmrClocks[QTMR_GetInstance(base)]); |
75 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
76 | |
77 | /* Setup the counter sources */ |
78 | base->CHANNEL[channel].CTRL = (TMR_CTRL_PCS(config->primarySource) | TMR_CTRL_SCS(config->secondarySource)); |
79 | |
80 | /* Setup the master mode operation */ |
81 | base->CHANNEL[channel].SCTRL = |
82 | (TMR_SCTRL_EEOF(config->enableExternalForce) | TMR_SCTRL_MSTR(config->enableMasterMode)); |
83 | |
84 | /* Setup debug mode */ |
85 | base->CHANNEL[channel].CSCTRL = TMR_CSCTRL_DBG_EN(config->debugMode); |
86 | |
87 | base->CHANNEL[channel].FILT &= (uint16_t)(~(TMR_FILT_FILT_CNT_MASK | TMR_FILT_FILT_PER_MASK)); |
88 | /* Setup input filter */ |
89 | base->CHANNEL[channel].FILT = |
90 | (TMR_FILT_FILT_CNT(config->faultFilterCount) | TMR_FILT_FILT_PER(config->faultFilterPeriod)); |
91 | } |
92 | |
93 | /*! |
94 | * brief Stops the counter and gates the Quad Timer clock |
95 | * |
96 | * param base Quad Timer peripheral base address |
97 | * param channel Quad Timer channel number |
98 | */ |
99 | void QTMR_Deinit(TMR_Type *base, qtmr_channel_selection_t channel) |
100 | { |
101 | /* Stop the counter */ |
102 | base->CHANNEL[channel].CTRL &= (uint16_t)(~TMR_CTRL_CM_MASK); |
103 | |
104 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
105 | /* Disable the module clock */ |
106 | CLOCK_DisableClock(s_qtmrClocks[QTMR_GetInstance(base)]); |
107 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
108 | } |
109 | |
110 | /*! |
111 | * brief Fill in the Quad Timer config struct with the default settings |
112 | * |
113 | * The default values are: |
114 | * code |
115 | * config->debugMode = kQTMR_RunNormalInDebug; |
116 | * config->enableExternalForce = false; |
117 | * config->enableMasterMode = false; |
118 | * config->faultFilterCount = 0; |
119 | * config->faultFilterPeriod = 0; |
120 | * config->primarySource = kQTMR_ClockDivide_2; |
121 | * config->secondarySource = kQTMR_Counter0InputPin; |
122 | * endcode |
123 | * param config Pointer to user's Quad Timer config structure. |
124 | */ |
125 | void QTMR_GetDefaultConfig(qtmr_config_t *config) |
126 | { |
127 | assert(NULL != config); |
128 | |
129 | /* Initializes the configure structure to zero. */ |
130 | (void)memset(config, 0, sizeof(*config)); |
131 | |
132 | /* Halt counter during debug mode */ |
133 | config->debugMode = kQTMR_RunNormalInDebug; |
134 | /* Another counter cannot force state of OFLAG signal */ |
135 | config->enableExternalForce = false; |
136 | /* Compare function's output from this counter is not broadcast to other counters */ |
137 | config->enableMasterMode = false; |
138 | /* Fault filter count is set to 0 */ |
139 | config->faultFilterCount = 0; |
140 | /* Fault filter period is set to 0 which disables the fault filter */ |
141 | config->faultFilterPeriod = 0; |
142 | /* Primary count source is IP bus clock divide by 2 */ |
143 | config->primarySource = kQTMR_ClockDivide_2; |
144 | /* Secondary count source is counter 0 input pin */ |
145 | config->secondarySource = kQTMR_Counter0InputPin; |
146 | } |
147 | |
148 | /*! |
149 | * brief Sets up Quad timer module for PWM signal output. |
150 | * |
151 | * The function initializes the timer module according to the parameters passed in by the user. The |
152 | * function also sets up the value compare registers to match the PWM signal requirements. |
153 | * |
154 | * param base Quad Timer peripheral base address |
155 | * param channel Quad Timer channel number |
156 | * param pwmFreqHz PWM signal frequency in Hz |
157 | * param dutyCyclePercent PWM pulse width, value should be between 0 to 100 |
158 | * 0=inactive signal(0% duty cycle)... |
159 | * 100=active signal (100% duty cycle) |
160 | * param outputPolarity true: invert polarity of the output signal, false: no inversion |
161 | * param srcClock_Hz Main counter clock in Hz. |
162 | * |
163 | * return Returns an error if there was error setting up the signal. |
164 | */ |
165 | status_t QTMR_SetupPwm(TMR_Type *base, |
166 | qtmr_channel_selection_t channel, |
167 | uint32_t pwmFreqHz, |
168 | uint8_t dutyCyclePercent, |
169 | bool outputPolarity, |
170 | uint32_t srcClock_Hz) |
171 | { |
172 | uint32_t periodCount, highCount, lowCount; |
173 | uint16_t reg; |
174 | status_t status; |
175 | |
176 | if (dutyCyclePercent <= 100U) |
177 | { |
178 | /* Set OFLAG pin for output mode and force out a low on the pin */ |
179 | base->CHANNEL[channel].SCTRL |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_OEN_MASK); |
180 | |
181 | /* Counter values to generate a PWM signal */ |
182 | periodCount = srcClock_Hz / pwmFreqHz; |
183 | highCount = periodCount * dutyCyclePercent / 100U; |
184 | lowCount = periodCount - highCount; |
185 | |
186 | if (highCount > 0U) |
187 | { |
188 | highCount -= 1U; |
189 | } |
190 | if (lowCount > 0U) |
191 | { |
192 | lowCount -= 1U; |
193 | } |
194 | |
195 | /* This should not be a 16-bit overflow value. If it is, change to a larger divider for clock source. */ |
196 | assert(highCount <= 0xFFFFU); |
197 | assert(lowCount <= 0xFFFFU); |
198 | |
199 | /* Setup the compare registers for PWM output */ |
200 | base->CHANNEL[channel].COMP1 = (uint16_t)lowCount; |
201 | base->CHANNEL[channel].COMP2 = (uint16_t)highCount; |
202 | |
203 | /* Setup the pre-load registers for PWM output */ |
204 | base->CHANNEL[channel].CMPLD1 = (uint16_t)lowCount; |
205 | base->CHANNEL[channel].CMPLD2 = (uint16_t)highCount; |
206 | |
207 | reg = base->CHANNEL[channel].CSCTRL; |
208 | /* Setup the compare load control for COMP1 and COMP2. |
209 | * Load COMP1 when CSCTRL[TCF2] is asserted, load COMP2 when CSCTRL[TCF1] is asserted |
210 | */ |
211 | reg &= (uint16_t)(~(TMR_CSCTRL_CL1_MASK | TMR_CSCTRL_CL2_MASK)); |
212 | reg |= (TMR_CSCTRL_CL1(kQTMR_LoadOnComp2) | TMR_CSCTRL_CL2(kQTMR_LoadOnComp1)); |
213 | base->CHANNEL[channel].CSCTRL = reg; |
214 | |
215 | if (outputPolarity) |
216 | { |
217 | /* Invert the polarity */ |
218 | base->CHANNEL[channel].SCTRL |= TMR_SCTRL_OPS_MASK; |
219 | } |
220 | else |
221 | { |
222 | /* True polarity, no inversion */ |
223 | base->CHANNEL[channel].SCTRL &= ~(uint16_t)TMR_SCTRL_OPS_MASK; |
224 | } |
225 | |
226 | reg = base->CHANNEL[channel].CTRL; |
227 | reg &= ~(uint16_t)TMR_CTRL_OUTMODE_MASK; |
228 | /* Count until compare value is reached and re-initialize the counter, toggle OFLAG output |
229 | * using alternating compare register |
230 | */ |
231 | reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg)); |
232 | base->CHANNEL[channel].CTRL = reg; |
233 | |
234 | status = kStatus_Success; |
235 | } |
236 | else |
237 | { |
238 | /* Invalid dutycycle */ |
239 | status = kStatus_Fail; |
240 | } |
241 | |
242 | return status; |
243 | } |
244 | |
245 | /*! |
246 | * brief Allows the user to count the source clock cycles until a capture event arrives. |
247 | * |
248 | * The count is stored in the capture register. |
249 | * |
250 | * param base Quad Timer peripheral base address |
251 | * param channel Quad Timer channel number |
252 | * param capturePin Pin through which we receive the input signal to trigger the capture |
253 | * param inputPolarity true: invert polarity of the input signal, false: no inversion |
254 | * param reloadOnCapture true: reload the counter when an input capture occurs, false: no reload |
255 | * param captureMode Specifies which edge of the input signal triggers a capture |
256 | */ |
257 | void QTMR_SetupInputCapture(TMR_Type *base, |
258 | qtmr_channel_selection_t channel, |
259 | qtmr_input_source_t capturePin, |
260 | bool inputPolarity, |
261 | bool reloadOnCapture, |
262 | qtmr_input_capture_edge_t captureMode) |
263 | { |
264 | uint16_t reg; |
265 | |
266 | /* Clear the prior value for the input source for capture */ |
267 | reg = base->CHANNEL[channel].CTRL & (uint16_t)(~TMR_CTRL_SCS_MASK); |
268 | |
269 | /* Set the new input source */ |
270 | reg |= TMR_CTRL_SCS(capturePin); |
271 | base->CHANNEL[channel].CTRL = reg; |
272 | |
273 | /* Clear the prior values for input polarity, capture mode. Set the external pin as input */ |
274 | reg = base->CHANNEL[channel].SCTRL & |
275 | (uint16_t)(~(TMR_SCTRL_IPS_MASK | TMR_SCTRL_CAPTURE_MODE_MASK | TMR_SCTRL_OEN_MASK)); |
276 | /* Set the new values */ |
277 | reg |= (TMR_SCTRL_IPS(inputPolarity) | TMR_SCTRL_CAPTURE_MODE(captureMode)); |
278 | base->CHANNEL[channel].SCTRL = reg; |
279 | |
280 | /* Setup if counter should reload when a capture occurs */ |
281 | if (reloadOnCapture) |
282 | { |
283 | base->CHANNEL[channel].CSCTRL |= TMR_CSCTRL_ROC_MASK; |
284 | } |
285 | else |
286 | { |
287 | base->CHANNEL[channel].CSCTRL &= (uint16_t)(~TMR_CSCTRL_ROC_MASK); |
288 | } |
289 | } |
290 | |
291 | /*! |
292 | * brief Enables the selected Quad Timer interrupts |
293 | * |
294 | * param base Quad Timer peripheral base address |
295 | * param channel Quad Timer channel number |
296 | * param mask The interrupts to enable. This is a logical OR of members of the |
297 | * enumeration ::qtmr_interrupt_enable_t |
298 | */ |
299 | void QTMR_EnableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) |
300 | { |
301 | uint16_t reg; |
302 | |
303 | reg = base->CHANNEL[channel].SCTRL; |
304 | /* Compare interrupt */ |
305 | if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL) |
306 | { |
307 | reg |= TMR_SCTRL_TCFIE_MASK; |
308 | } |
309 | /* Overflow interrupt */ |
310 | if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL) |
311 | { |
312 | reg |= TMR_SCTRL_TOFIE_MASK; |
313 | } |
314 | /* Input edge interrupt */ |
315 | if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL) |
316 | { |
317 | /* Restriction: Do not set both SCTRL[IEFIE] and DMA[IEFDE] */ |
318 | base->CHANNEL[channel].DMA &= ~(uint16_t)TMR_DMA_IEFDE_MASK; |
319 | reg |= TMR_SCTRL_IEFIE_MASK; |
320 | } |
321 | base->CHANNEL[channel].SCTRL = reg; |
322 | |
323 | reg = base->CHANNEL[channel].CSCTRL; |
324 | /* Compare 1 interrupt */ |
325 | if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL) |
326 | { |
327 | reg |= TMR_CSCTRL_TCF1EN_MASK; |
328 | } |
329 | /* Compare 2 interrupt */ |
330 | if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL) |
331 | { |
332 | reg |= TMR_CSCTRL_TCF2EN_MASK; |
333 | } |
334 | base->CHANNEL[channel].CSCTRL = reg; |
335 | } |
336 | |
337 | /*! |
338 | * brief Disables the selected Quad Timer interrupts |
339 | * |
340 | * param base Quad Timer peripheral base addres |
341 | * param channel Quad Timer channel number |
342 | * param mask The interrupts to enable. This is a logical OR of members of the |
343 | * enumeration ::qtmr_interrupt_enable_t |
344 | */ |
345 | void QTMR_DisableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) |
346 | { |
347 | uint16_t reg; |
348 | |
349 | reg = base->CHANNEL[channel].SCTRL; |
350 | /* Compare interrupt */ |
351 | if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL) |
352 | { |
353 | reg &= (uint16_t)(~TMR_SCTRL_TCFIE_MASK); |
354 | } |
355 | /* Overflow interrupt */ |
356 | if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL) |
357 | { |
358 | reg &= (uint16_t)(~TMR_SCTRL_TOFIE_MASK); |
359 | } |
360 | /* Input edge interrupt */ |
361 | if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL) |
362 | { |
363 | reg &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK); |
364 | } |
365 | base->CHANNEL[channel].SCTRL = reg; |
366 | |
367 | reg = base->CHANNEL[channel].CSCTRL; |
368 | /* Compare 1 interrupt */ |
369 | if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL) |
370 | { |
371 | reg &= ~(uint16_t)TMR_CSCTRL_TCF1EN_MASK; |
372 | } |
373 | /* Compare 2 interrupt */ |
374 | if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL) |
375 | { |
376 | reg &= ~(uint16_t)TMR_CSCTRL_TCF2EN_MASK; |
377 | } |
378 | base->CHANNEL[channel].CSCTRL = reg; |
379 | } |
380 | |
381 | /*! |
382 | * brief Gets the enabled Quad Timer interrupts |
383 | * |
384 | * param base Quad Timer peripheral base address |
385 | * param channel Quad Timer channel number |
386 | * |
387 | * return The enabled interrupts. This is the logical OR of members of the |
388 | * enumeration ::qtmr_interrupt_enable_t |
389 | */ |
390 | uint32_t QTMR_GetEnabledInterrupts(TMR_Type *base, qtmr_channel_selection_t channel) |
391 | { |
392 | uint32_t enabledInterrupts = 0; |
393 | uint16_t reg; |
394 | |
395 | reg = base->CHANNEL[channel].SCTRL; |
396 | /* Compare interrupt */ |
397 | if ((reg & TMR_SCTRL_TCFIE_MASK) != 0U) |
398 | { |
399 | enabledInterrupts |= (uint32_t)kQTMR_CompareFlag; |
400 | } |
401 | /* Overflow interrupt */ |
402 | if ((reg & TMR_SCTRL_TOFIE_MASK) != 0U) |
403 | { |
404 | enabledInterrupts |= (uint32_t)kQTMR_OverflowInterruptEnable; |
405 | } |
406 | /* Input edge interrupt */ |
407 | if ((reg & TMR_SCTRL_IEFIE_MASK) != 0U) |
408 | { |
409 | enabledInterrupts |= (uint32_t)kQTMR_EdgeInterruptEnable; |
410 | } |
411 | |
412 | reg = base->CHANNEL[channel].CSCTRL; |
413 | /* Compare 1 interrupt */ |
414 | if ((reg & TMR_CSCTRL_TCF1EN_MASK) != 0U) |
415 | { |
416 | enabledInterrupts |= (uint32_t)kQTMR_Compare1InterruptEnable; |
417 | } |
418 | /* Compare 2 interrupt */ |
419 | if ((reg & TMR_CSCTRL_TCF2EN_MASK) != 0U) |
420 | { |
421 | enabledInterrupts |= (uint32_t)kQTMR_Compare2InterruptEnable; |
422 | } |
423 | |
424 | return enabledInterrupts; |
425 | } |
426 | |
427 | /*! |
428 | * brief Gets the Quad Timer status flags |
429 | * |
430 | * param base Quad Timer peripheral base address |
431 | * param channel Quad Timer channel number |
432 | * |
433 | * return The status flags. This is the logical OR of members of the |
434 | * enumeration ::qtmr_status_flags_t |
435 | */ |
436 | uint32_t QTMR_GetStatus(TMR_Type *base, qtmr_channel_selection_t channel) |
437 | { |
438 | uint32_t statusFlags = 0; |
439 | uint16_t reg; |
440 | |
441 | reg = base->CHANNEL[channel].SCTRL; |
442 | /* Timer compare flag */ |
443 | if ((reg & TMR_SCTRL_TCF_MASK) != 0U) |
444 | { |
445 | statusFlags |= (uint32_t)kQTMR_CompareFlag; |
446 | } |
447 | /* Timer overflow flag */ |
448 | if ((reg & TMR_SCTRL_TOF_MASK) != 0U) |
449 | { |
450 | statusFlags |= (uint32_t)kQTMR_OverflowFlag; |
451 | } |
452 | /* Input edge flag */ |
453 | if ((reg & TMR_SCTRL_IEF_MASK) != 0U) |
454 | { |
455 | statusFlags |= (uint32_t)kQTMR_EdgeFlag; |
456 | } |
457 | |
458 | reg = base->CHANNEL[channel].CSCTRL; |
459 | /* Compare 1 flag */ |
460 | if ((reg & TMR_CSCTRL_TCF1_MASK) != 0U) |
461 | { |
462 | statusFlags |= (uint32_t)kQTMR_Compare1Flag; |
463 | } |
464 | /* Compare 2 flag */ |
465 | if ((reg & TMR_CSCTRL_TCF2_MASK) != 0U) |
466 | { |
467 | statusFlags |= (uint32_t)kQTMR_Compare2Flag; |
468 | } |
469 | |
470 | return statusFlags; |
471 | } |
472 | |
473 | /*! |
474 | * brief Clears the Quad Timer status flags. |
475 | * |
476 | * param base Quad Timer peripheral base address |
477 | * param channel Quad Timer channel number |
478 | * param mask The status flags to clear. This is a logical OR of members of the |
479 | * enumeration ::qtmr_status_flags_t |
480 | */ |
481 | void QTMR_ClearStatusFlags(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) |
482 | { |
483 | uint16_t reg; |
484 | |
485 | reg = base->CHANNEL[channel].SCTRL; |
486 | /* Timer compare flag */ |
487 | if ((mask & (uint32_t)kQTMR_CompareFlag) != 0U) |
488 | { |
489 | reg &= (uint16_t)(~TMR_SCTRL_TCF_MASK); |
490 | } |
491 | /* Timer overflow flag */ |
492 | if ((mask & (uint32_t)kQTMR_OverflowFlag) != 0U) |
493 | { |
494 | reg &= (uint16_t)(~TMR_SCTRL_TOF_MASK); |
495 | } |
496 | /* Input edge flag */ |
497 | if ((mask & (uint32_t)kQTMR_EdgeFlag) != 0U) |
498 | { |
499 | reg &= (uint16_t)(~TMR_SCTRL_IEF_MASK); |
500 | } |
501 | base->CHANNEL[channel].SCTRL = reg; |
502 | |
503 | reg = base->CHANNEL[channel].CSCTRL; |
504 | /* Compare 1 flag */ |
505 | if ((mask & (uint32_t)kQTMR_Compare1Flag) != 0U) |
506 | { |
507 | reg &= ~(uint16_t)TMR_CSCTRL_TCF1_MASK; |
508 | } |
509 | /* Compare 2 flag */ |
510 | if ((mask & (uint32_t)kQTMR_Compare2Flag) != 0U) |
511 | { |
512 | reg &= ~(uint16_t)TMR_CSCTRL_TCF2_MASK; |
513 | } |
514 | base->CHANNEL[channel].CSCTRL = reg; |
515 | } |
516 | |
517 | /*! |
518 | * brief Sets the timer period in ticks. |
519 | * |
520 | * Timers counts from initial value till it equals the count value set here. The counter |
521 | * will then reinitialize to the value specified in the Load register. |
522 | * |
523 | * note |
524 | * 1. This function will write the time period in ticks to COMP1 or COMP2 register |
525 | * depending on the count direction |
526 | * 2. User can call the utility macros provided in fsl_common.h to convert to ticks |
527 | * 3. This function supports cases, providing only primary source clock without secondary source clock. |
528 | * |
529 | * param base Quad Timer peripheral base address |
530 | * param channel Quad Timer channel number |
531 | * param ticks Timer period in units of ticks |
532 | */ |
533 | void QTMR_SetTimerPeriod(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t ticks) |
534 | { |
535 | /* Set the length bit to reinitialize the counters on a match */ |
536 | base->CHANNEL[channel].CTRL |= TMR_CTRL_LENGTH_MASK; |
537 | |
538 | if ((base->CHANNEL[channel].CTRL & TMR_CTRL_DIR_MASK) != 0U) |
539 | { |
540 | /* Counting down */ |
541 | base->CHANNEL[channel].COMP2 = ticks; |
542 | } |
543 | else |
544 | { |
545 | /* Counting up */ |
546 | base->CHANNEL[channel].COMP1 = ticks; |
547 | } |
548 | } |
549 | |
550 | /*! |
551 | * brief Enable the Quad Timer DMA. |
552 | * |
553 | * param base Quad Timer peripheral base address |
554 | * param channel Quad Timer channel number |
555 | * param mask The DMA to enable. This is a logical OR of members of the |
556 | * enumeration ::qtmr_dma_enable_t |
557 | */ |
558 | void QTMR_EnableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) |
559 | { |
560 | uint16_t reg; |
561 | |
562 | reg = base->CHANNEL[channel].DMA; |
563 | /* Input Edge Flag DMA Enable */ |
564 | if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U) |
565 | { |
566 | /* Restriction: Do not set both DMA[IEFDE] and SCTRL[IEFIE] */ |
567 | base->CHANNEL[channel].SCTRL &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK); |
568 | reg |= TMR_DMA_IEFDE_MASK; |
569 | } |
570 | /* Comparator Preload Register 1 DMA Enable */ |
571 | if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U) |
572 | { |
573 | reg |= TMR_DMA_CMPLD1DE_MASK; |
574 | } |
575 | /* Comparator Preload Register 2 DMA Enable */ |
576 | if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U) |
577 | { |
578 | reg |= TMR_DMA_CMPLD2DE_MASK; |
579 | } |
580 | base->CHANNEL[channel].DMA = reg; |
581 | } |
582 | |
583 | /*! |
584 | * brief Disable the Quad Timer DMA. |
585 | * |
586 | * param base Quad Timer peripheral base address |
587 | * param channel Quad Timer channel number |
588 | * param mask The DMA to enable. This is a logical OR of members of the |
589 | * enumeration ::qtmr_dma_enable_t |
590 | */ |
591 | void QTMR_DisableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) |
592 | { |
593 | uint16_t reg; |
594 | |
595 | reg = base->CHANNEL[channel].DMA; |
596 | /* Input Edge Flag DMA Enable */ |
597 | if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U) |
598 | { |
599 | reg &= ~(uint16_t)TMR_DMA_IEFDE_MASK; |
600 | } |
601 | /* Comparator Preload Register 1 DMA Enable */ |
602 | if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U) |
603 | { |
604 | reg &= ~(uint16_t)TMR_DMA_CMPLD1DE_MASK; |
605 | } |
606 | /* Comparator Preload Register 2 DMA Enable */ |
607 | if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U) |
608 | { |
609 | reg &= ~(uint16_t)TMR_DMA_CMPLD2DE_MASK; |
610 | } |
611 | base->CHANNEL[channel].DMA = reg; |
612 | } |
613 | |