fsl_qtmr.c 20 KB

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