fsl_sctimer.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_sctimer.h"
  31. /*******************************************************************************
  32. * Definitions
  33. ******************************************************************************/
  34. /*! @brief Typedef for interrupt handler. */
  35. typedef void (*sctimer_isr_t)(SCT_Type *base);
  36. /*******************************************************************************
  37. * Prototypes
  38. ******************************************************************************/
  39. /*!
  40. * @brief Gets the instance from the base address
  41. *
  42. * @param base SCTimer peripheral base address
  43. *
  44. * @return The SCTimer instance
  45. */
  46. static uint32_t SCTIMER_GetInstance(SCT_Type *base);
  47. /*******************************************************************************
  48. * Variables
  49. ******************************************************************************/
  50. /*! @brief Pointers to SCT bases for each instance. */
  51. static SCT_Type *const s_sctBases[] = SCT_BASE_PTRS;
  52. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  53. /*! @brief Pointers to SCT clocks for each instance. */
  54. static const clock_ip_name_t s_sctClocks[] = SCT_CLOCKS;
  55. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  56. /*! @brief Pointers to SCT resets for each instance. */
  57. static const reset_ip_name_t s_sctResets[] = SCT_RSTS;
  58. /*!< @brief SCTimer event Callback function. */
  59. static sctimer_event_callback_t s_eventCallback[FSL_FEATURE_SCT_NUMBER_OF_EVENTS];
  60. /*!< @brief Keep track of SCTimer event number */
  61. static uint32_t s_currentEvent;
  62. /*!< @brief Keep track of SCTimer state number */
  63. static uint32_t s_currentState;
  64. /*!< @brief Keep track of SCTimer match/capture register number */
  65. static uint32_t s_currentMatch;
  66. /*! @brief Pointer to SCTimer IRQ handler */
  67. static sctimer_isr_t s_sctimerIsr;
  68. /*******************************************************************************
  69. * Code
  70. ******************************************************************************/
  71. static uint32_t SCTIMER_GetInstance(SCT_Type *base)
  72. {
  73. uint32_t instance;
  74. uint32_t sctArrayCount = (sizeof(s_sctBases) / sizeof(s_sctBases[0]));
  75. /* Find the instance index from base address mappings. */
  76. for (instance = 0; instance < sctArrayCount; instance++)
  77. {
  78. if (s_sctBases[instance] == base)
  79. {
  80. break;
  81. }
  82. }
  83. assert(instance < sctArrayCount);
  84. return instance;
  85. }
  86. status_t SCTIMER_Init(SCT_Type *base, const sctimer_config_t *config)
  87. {
  88. assert(config);
  89. uint32_t i;
  90. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  91. /* Enable the SCTimer clock*/
  92. CLOCK_EnableClock(s_sctClocks[SCTIMER_GetInstance(base)]);
  93. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  94. /* Reset the module */
  95. RESET_PeripheralReset(s_sctResets[SCTIMER_GetInstance(base)]);
  96. /* Setup the counter operation */
  97. base->CONFIG = SCT_CONFIG_CKSEL(config->clockSelect) | SCT_CONFIG_CLKMODE(config->clockMode) |
  98. SCT_CONFIG_UNIFY(config->enableCounterUnify);
  99. /* Write to the control register, clear the counter and keep the counters halted */
  100. base->CTRL = SCT_CTRL_BIDIR_L(config->enableBidirection_l) | SCT_CTRL_PRE_L(config->prescale_l) |
  101. SCT_CTRL_CLRCTR_L_MASK | SCT_CTRL_HALT_L_MASK;
  102. if (!(config->enableCounterUnify))
  103. {
  104. base->CTRL |= SCT_CTRL_BIDIR_H(config->enableBidirection_h) | SCT_CTRL_PRE_H(config->prescale_h) |
  105. SCT_CTRL_CLRCTR_H_MASK | SCT_CTRL_HALT_H_MASK;
  106. }
  107. /* Initial state of channel output */
  108. base->OUTPUT = config->outInitState;
  109. /* Clear the global variables */
  110. s_currentEvent = 0;
  111. s_currentState = 0;
  112. s_currentMatch = 0;
  113. /* Clear the callback array */
  114. for (i = 0; i < FSL_FEATURE_SCT_NUMBER_OF_EVENTS; i++)
  115. {
  116. s_eventCallback[i] = NULL;
  117. }
  118. /* Save interrupt handler */
  119. s_sctimerIsr = SCTIMER_EventHandleIRQ;
  120. return kStatus_Success;
  121. }
  122. void SCTIMER_Deinit(SCT_Type *base)
  123. {
  124. /* Halt the counters */
  125. base->CTRL |= (SCT_CTRL_HALT_L_MASK | SCT_CTRL_HALT_H_MASK);
  126. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  127. /* Disable the SCTimer clock*/
  128. CLOCK_DisableClock(s_sctClocks[SCTIMER_GetInstance(base)]);
  129. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  130. }
  131. void SCTIMER_GetDefaultConfig(sctimer_config_t *config)
  132. {
  133. assert(config);
  134. /* SCT operates as a unified 32-bit counter */
  135. config->enableCounterUnify = true;
  136. /* System clock clocks the entire SCT module */
  137. config->clockMode = kSCTIMER_System_ClockMode;
  138. /* This is used only by certain clock modes */
  139. config->clockSelect = kSCTIMER_Clock_On_Rise_Input_0;
  140. /* Up count mode only for the unified counter */
  141. config->enableBidirection_l = false;
  142. /* Up count mode only for Counte_H */
  143. config->enableBidirection_h = false;
  144. /* Prescale factor of 1 */
  145. config->prescale_l = 0;
  146. /* Prescale factor of 1 for Counter_H*/
  147. config->prescale_h = 0;
  148. /* Clear outputs */
  149. config->outInitState = 0;
  150. }
  151. status_t SCTIMER_SetupPwm(SCT_Type *base,
  152. const sctimer_pwm_signal_param_t *pwmParams,
  153. sctimer_pwm_mode_t mode,
  154. uint32_t pwmFreq_Hz,
  155. uint32_t srcClock_Hz,
  156. uint32_t *event)
  157. {
  158. assert(pwmParams);
  159. assert(srcClock_Hz);
  160. assert(pwmFreq_Hz);
  161. uint32_t period, pulsePeriod = 0;
  162. uint32_t sctClock = srcClock_Hz / (((base->CTRL & SCT_CTRL_PRE_L_MASK) >> SCT_CTRL_PRE_L_SHIFT) + 1);
  163. uint32_t periodEvent, pulseEvent;
  164. uint32_t reg;
  165. /* This function will create 2 events, return an error if we do not have enough events available */
  166. if ((s_currentEvent + 2) > FSL_FEATURE_SCT_NUMBER_OF_EVENTS)
  167. {
  168. return kStatus_Fail;
  169. }
  170. if (pwmParams->dutyCyclePercent == 0)
  171. {
  172. return kStatus_Fail;
  173. }
  174. /* Set unify bit to operate in 32-bit counter mode */
  175. base->CONFIG |= SCT_CONFIG_UNIFY_MASK;
  176. /* Use bi-directional mode for center-aligned PWM */
  177. if (mode == kSCTIMER_CenterAlignedPwm)
  178. {
  179. base->CTRL |= SCT_CTRL_BIDIR_L_MASK;
  180. }
  181. /* Calculate PWM period match value */
  182. if (mode == kSCTIMER_EdgeAlignedPwm)
  183. {
  184. period = (sctClock / pwmFreq_Hz) - 1;
  185. }
  186. else
  187. {
  188. period = sctClock / (pwmFreq_Hz * 2);
  189. }
  190. /* Calculate pulse width match value */
  191. pulsePeriod = (period * pwmParams->dutyCyclePercent) / 100;
  192. /* For 100% dutycyle, make pulse period greater than period so the event will never occur */
  193. if (pwmParams->dutyCyclePercent >= 100)
  194. {
  195. pulsePeriod = period + 2;
  196. }
  197. /* Schedule an event when we reach the PWM period */
  198. SCTIMER_CreateAndScheduleEvent(base, kSCTIMER_MatchEventOnly, period, 0, kSCTIMER_Counter_L, &periodEvent);
  199. /* Schedule an event when we reach the pulse width */
  200. SCTIMER_CreateAndScheduleEvent(base, kSCTIMER_MatchEventOnly, pulsePeriod, 0, kSCTIMER_Counter_L, &pulseEvent);
  201. /* Reset the counter when we reach the PWM period */
  202. SCTIMER_SetupCounterLimitAction(base, kSCTIMER_Counter_L, periodEvent);
  203. /* Return the period event to the user */
  204. *event = periodEvent;
  205. /* For high-true level */
  206. if (pwmParams->level == kSCTIMER_HighTrue)
  207. {
  208. /* Set the initial output level to low which is the inactive state */
  209. base->OUTPUT &= ~(1U << pwmParams->output);
  210. if (mode == kSCTIMER_EdgeAlignedPwm)
  211. {
  212. /* Set the output when we reach the PWM period */
  213. SCTIMER_SetupOutputSetAction(base, pwmParams->output, periodEvent);
  214. /* Clear the output when we reach the PWM pulse value */
  215. SCTIMER_SetupOutputClearAction(base, pwmParams->output, pulseEvent);
  216. }
  217. else
  218. {
  219. /* Clear the output when we reach the PWM pulse event */
  220. SCTIMER_SetupOutputClearAction(base, pwmParams->output, pulseEvent);
  221. /* Reverse output when down counting */
  222. reg = base->OUTPUTDIRCTRL;
  223. reg &= ~(SCT_OUTPUTDIRCTRL_SETCLR0_MASK << (2 * pwmParams->output));
  224. reg |= (1U << (2 * pwmParams->output));
  225. base->OUTPUTDIRCTRL = reg;
  226. }
  227. }
  228. /* For low-true level */
  229. else
  230. {
  231. /* Set the initial output level to high which is the inactive state */
  232. base->OUTPUT |= (1U << pwmParams->output);
  233. if (mode == kSCTIMER_EdgeAlignedPwm)
  234. {
  235. /* Clear the output when we reach the PWM period */
  236. SCTIMER_SetupOutputClearAction(base, pwmParams->output, periodEvent);
  237. /* Set the output when we reach the PWM pulse value */
  238. SCTIMER_SetupOutputSetAction(base, pwmParams->output, pulseEvent);
  239. }
  240. else
  241. {
  242. /* Set the output when we reach the PWM pulse event */
  243. SCTIMER_SetupOutputSetAction(base, pwmParams->output, pulseEvent);
  244. /* Reverse output when down counting */
  245. reg = base->OUTPUTDIRCTRL;
  246. reg &= ~(SCT_OUTPUTDIRCTRL_SETCLR0_MASK << (2 * pwmParams->output));
  247. reg |= (1U << (2 * pwmParams->output));
  248. base->OUTPUTDIRCTRL = reg;
  249. }
  250. }
  251. return kStatus_Success;
  252. }
  253. void SCTIMER_UpdatePwmDutycycle(SCT_Type *base, sctimer_out_t output, uint8_t dutyCyclePercent, uint32_t event)
  254. {
  255. assert(dutyCyclePercent > 0);
  256. uint32_t periodMatchReg, pulseMatchReg;
  257. uint32_t pulsePeriod = 0, period;
  258. /* Retrieve the match register number for the PWM period */
  259. periodMatchReg = base->EVENT[event].CTRL & SCT_EVENT_CTRL_MATCHSEL_MASK;
  260. /* Retrieve the match register number for the PWM pulse period */
  261. pulseMatchReg = base->EVENT[event + 1].CTRL & SCT_EVENT_CTRL_MATCHSEL_MASK;
  262. period = base->SCTMATCH[periodMatchReg];
  263. /* Calculate pulse width match value */
  264. pulsePeriod = (period * dutyCyclePercent) / 100;
  265. /* For 100% dutycyle, make pulse period greater than period so the event will never occur */
  266. if (dutyCyclePercent >= 100)
  267. {
  268. pulsePeriod = period + 2;
  269. }
  270. /* Stop the counter before updating match register */
  271. SCTIMER_StopTimer(base, kSCTIMER_Counter_L);
  272. /* Update dutycycle */
  273. base->SCTMATCH[pulseMatchReg] = SCT_SCTMATCH_MATCHn_L(pulsePeriod);
  274. base->SCTMATCHREL[pulseMatchReg] = SCT_SCTMATCHREL_RELOADn_L(pulsePeriod);
  275. /* Restart the counter */
  276. SCTIMER_StartTimer(base, kSCTIMER_Counter_L);
  277. }
  278. status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base,
  279. sctimer_event_t howToMonitor,
  280. uint32_t matchValue,
  281. uint32_t whichIO,
  282. sctimer_counter_t whichCounter,
  283. uint32_t *event)
  284. {
  285. uint32_t combMode = (((uint32_t)howToMonitor & SCT_EVENT_CTRL_COMBMODE_MASK) >> SCT_EVENT_CTRL_COMBMODE_SHIFT);
  286. uint32_t currentCtrlVal = howToMonitor;
  287. /* Return an error if we have hit the limit in terms of number of events created */
  288. if (s_currentEvent >= FSL_FEATURE_SCT_NUMBER_OF_EVENTS)
  289. {
  290. return kStatus_Fail;
  291. }
  292. /* IO only mode */
  293. if (combMode == 0x2U)
  294. {
  295. base->EVENT[s_currentEvent].CTRL = currentCtrlVal | SCT_EVENT_CTRL_IOSEL(whichIO);
  296. }
  297. /* Match mode only */
  298. else if (combMode == 0x1U)
  299. {
  300. /* Return an error if we have hit the limit in terms of number of number of match registers */
  301. if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE)
  302. {
  303. return kStatus_Fail;
  304. }
  305. currentCtrlVal |= SCT_EVENT_CTRL_MATCHSEL(s_currentMatch);
  306. /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */
  307. if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
  308. {
  309. base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
  310. base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
  311. }
  312. else
  313. {
  314. /* Select the counter, no need for this if operating in 32-bit mode */
  315. currentCtrlVal |= SCT_EVENT_CTRL_HEVENT(whichCounter);
  316. base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_H(matchValue);
  317. base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_H(matchValue);
  318. }
  319. base->EVENT[s_currentEvent].CTRL = currentCtrlVal;
  320. /* Increment the match register number */
  321. s_currentMatch++;
  322. }
  323. /* Use both Match & IO */
  324. else
  325. {
  326. /* Return an error if we have hit the limit in terms of number of number of match registers */
  327. if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE)
  328. {
  329. return kStatus_Fail;
  330. }
  331. currentCtrlVal |= SCT_EVENT_CTRL_MATCHSEL(s_currentMatch) | SCT_EVENT_CTRL_IOSEL(whichIO);
  332. /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */
  333. if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
  334. {
  335. base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
  336. base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
  337. }
  338. else
  339. {
  340. /* Select the counter, no need for this if operating in 32-bit mode */
  341. currentCtrlVal |= SCT_EVENT_CTRL_HEVENT(whichCounter);
  342. base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_H(matchValue);
  343. base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_H(matchValue);
  344. }
  345. base->EVENT[s_currentEvent].CTRL = currentCtrlVal;
  346. /* Increment the match register number */
  347. s_currentMatch++;
  348. }
  349. /* Enable the event in the current state */
  350. base->EVENT[s_currentEvent].STATE = (1U << s_currentState);
  351. /* Return the event number */
  352. *event = s_currentEvent;
  353. /* Increment the event number */
  354. s_currentEvent++;
  355. return kStatus_Success;
  356. }
  357. void SCTIMER_ScheduleEvent(SCT_Type *base, uint32_t event)
  358. {
  359. /* Enable event in the current state */
  360. base->EVENT[event].STATE |= (1U << s_currentState);
  361. }
  362. status_t SCTIMER_IncreaseState(SCT_Type *base)
  363. {
  364. /* Return an error if we have hit the limit in terms of states used */
  365. if (s_currentState >= FSL_FEATURE_SCT_NUMBER_OF_STATES)
  366. {
  367. return kStatus_Fail;
  368. }
  369. s_currentState++;
  370. return kStatus_Success;
  371. }
  372. uint32_t SCTIMER_GetCurrentState(SCT_Type *base)
  373. {
  374. return s_currentState;
  375. }
  376. void SCTIMER_SetupOutputToggleAction(SCT_Type *base, uint32_t whichIO, uint32_t event)
  377. {
  378. uint32_t reg;
  379. /* Set the same event to set and clear the output */
  380. base->OUT[whichIO].CLR |= (1U << event);
  381. base->OUT[whichIO].SET |= (1U << event);
  382. /* Set the conflict resolution to toggle output */
  383. reg = base->RES;
  384. reg &= ~(SCT_RES_O0RES_MASK << (2 * whichIO));
  385. reg |= (uint32_t)(kSCTIMER_ResolveToggle << (2 * whichIO));
  386. base->RES = reg;
  387. }
  388. status_t SCTIMER_SetupCaptureAction(SCT_Type *base,
  389. sctimer_counter_t whichCounter,
  390. uint32_t *captureRegister,
  391. uint32_t event)
  392. {
  393. /* Return an error if we have hit the limit in terms of number of capture/match registers used */
  394. if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE)
  395. {
  396. return kStatus_Fail;
  397. }
  398. /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */
  399. if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
  400. {
  401. /* Set the bit to enable event */
  402. base->SCTCAPCTRL[s_currentMatch] |= SCT_SCTCAPCTRL_CAPCONn_L(1 << event);
  403. /* Set this resource to be a capture rather than match */
  404. base->REGMODE |= SCT_REGMODE_REGMOD_L(1 << s_currentMatch);
  405. }
  406. else
  407. {
  408. /* Set bit to enable event */
  409. base->SCTCAPCTRL[s_currentMatch] |= SCT_SCTCAPCTRL_CAPCONn_H(1 << event);
  410. /* Set this resource to be a capture rather than match */
  411. base->REGMODE |= SCT_REGMODE_REGMOD_H(1 << s_currentMatch);
  412. }
  413. /* Return the match register number */
  414. *captureRegister = s_currentMatch;
  415. /* Increase the match register number */
  416. s_currentMatch++;
  417. return kStatus_Success;
  418. }
  419. void SCTIMER_SetCallback(SCT_Type *base, sctimer_event_callback_t callback, uint32_t event)
  420. {
  421. s_eventCallback[event] = callback;
  422. }
  423. void SCTIMER_EventHandleIRQ(SCT_Type *base)
  424. {
  425. uint32_t eventFlag = SCT0->EVFLAG;
  426. /* Only clear the flags whose interrupt field is enabled */
  427. uint32_t clearFlag = (eventFlag & SCT0->EVEN);
  428. uint32_t mask = eventFlag;
  429. int i = 0;
  430. /* Invoke the callback for certain events */
  431. for (i = 0; (i < FSL_FEATURE_SCT_NUMBER_OF_EVENTS) && (mask != 0); i++)
  432. {
  433. if (mask & 0x1)
  434. {
  435. if (s_eventCallback[i] != NULL)
  436. {
  437. s_eventCallback[i]();
  438. }
  439. }
  440. mask >>= 1;
  441. }
  442. /* Clear event interrupt flag */
  443. SCT0->EVFLAG = clearFlag;
  444. }
  445. void SCT0_IRQHandler(void)
  446. {
  447. s_sctimerIsr(SCT0);
  448. }