core_hwtimer.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "user.h"
  22. typedef struct
  23. {
  24. // const I2C_TypeDef *RegBase;
  25. const int IrqLine;
  26. OPQueue_CmdStruct *Cmd;
  27. CBFuncEx_t CmdDoneCB;
  28. void *pCmdDoneParam;
  29. uint32_t TotalCount;
  30. uint32_t TotalRepeat;
  31. uint32_t CurCount;
  32. uint32_t RepeatCnt;
  33. uint32_t CmdQueuePos;
  34. uint8_t IsQueueRunning;
  35. uint8_t ContinueDelay;
  36. }HWTimer_CtrlStruct;
  37. static HWTimer_CtrlStruct prvHWTimer[HW_TIMER_MAX] = {
  38. {
  39. // TIMM0,
  40. TIM0_0_IRQn,
  41. NULL,
  42. {
  43. NULL, 0, 0,
  44. }
  45. },
  46. {
  47. // TIMM0,
  48. TIM0_1_IRQn,
  49. NULL,
  50. {
  51. NULL, 0, 0,
  52. }
  53. },
  54. {
  55. // TIMM0,
  56. TIM0_2_IRQn,
  57. NULL,
  58. {
  59. NULL, 0, 0,
  60. }
  61. },
  62. {
  63. // TIMM0,
  64. TIM0_3_IRQn,
  65. NULL,
  66. {
  67. NULL, 0, 0,
  68. }
  69. },
  70. {
  71. // TIMM0,
  72. TIM0_4_IRQn,
  73. NULL,
  74. {
  75. NULL, 0, 0,
  76. }
  77. },
  78. {
  79. // TIMM0,
  80. TIM0_5_IRQn,
  81. NULL,
  82. {
  83. NULL, 0, 0,
  84. }
  85. },
  86. };
  87. static void prvHWTimer_IrqHandlerOperationQueue( int32_t Line, void *pData);
  88. static void prvHWTimer_StartOperationQueue(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin);
  89. static int32_t __FUNC_IN_RAM__ prvHWTimer_DummyCB(void *pData, void *pParam)
  90. {
  91. return 0;
  92. }
  93. static void prvHWTimer_IrqHandlerEndOperationQueue( int32_t Line, void *pData)
  94. {
  95. uint32_t HWTimerID = (uint32_t)pData;
  96. HWTimer_Stop(HWTimerID);
  97. prvHWTimer[HWTimerID].CmdDoneCB(0, prvHWTimer[HWTimerID].pCmdDoneParam);
  98. }
  99. static int32_t __FUNC_IN_RAM__ prvHWTimer_OperationQueuExti(void *pData, void *pParam)
  100. {
  101. uint32_t HWTimerID = (uint32_t)pParam;
  102. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], (uint32_t)pData);
  103. return 0;
  104. }
  105. static void __FUNC_IN_RAM__ prvHWTimer_StartOperationQueue(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  106. {
  107. volatile uint32_t Period;
  108. while(HWTimer->IsQueueRunning)
  109. {
  110. // DBG("%u,%u,%u,%u,%u,%u,%u,%u,%u,%x", HWTimer->TotalRepeat, HWTimer->RepeatCnt,
  111. // HWTimer->TotalCount, HWTimer->CurCount, HWTimer->Cmd[HWTimer->CurCount].Operation,
  112. // HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level,
  113. // HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, HWTimer->Cmd[HWTimer->CurCount].uArg.Time,
  114. // HWTimer->Cmd[HWTimer->CurCount].CB);
  115. switch(HWTimer->Cmd[HWTimer->CurCount].Operation)
  116. {
  117. case OP_QUEUE_CMD_GPIO_OUT:
  118. GPIO_Output(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level);
  119. HWTimer->CurCount++;
  120. break;
  121. case OP_QUEUE_CMD_GPIO_IN_CB:
  122. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  123. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, &HWTimer->Cmd[HWTimer->CurCount]);
  124. HWTimer->CurCount++;
  125. break;
  126. case OP_QUEUE_CMD_GPIO_IN:
  127. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  128. HWTimer->CurCount++;
  129. break;
  130. case OP_QUEUE_CMD_ONE_TIME_DELAY:
  131. HWTimer->ContinueDelay = 0;
  132. goto START_HWTIMER;
  133. break;
  134. case OP_QUEUE_CMD_REPEAT_DELAY:
  135. HWTimer->CurCount++;
  136. return;
  137. break;
  138. case OP_QUEUE_CMD_CAPTURE:
  139. HWTimer->Cmd[HWTimer->CurCount].PinOrDelay = Pin;
  140. if (!TIMM0->TIM[HWTimerID].ControlReg)
  141. {
  142. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_CAPTURE_END;
  143. }
  144. else
  145. {
  146. HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt = TIMM0->TIM[HWTimerID].LoadCount - TIMM0->TIM[HWTimerID].CurrentValue;
  147. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  148. }
  149. HWTimer->CurCount++;
  150. if (OP_QUEUE_CMD_CAPTURE_END != HWTimer->Cmd[HWTimer->CurCount].Operation)
  151. {
  152. return;
  153. }
  154. break;
  155. case OP_QUEUE_CMD_CAPTURE_CB:
  156. HWTimer->Cmd[HWTimer->CurCount].PinOrDelay = Pin;
  157. if (!TIMM0->TIM[HWTimerID].ControlReg)
  158. {
  159. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_CAPTURE_END;
  160. }
  161. else
  162. {
  163. HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt = TIMM0->TIM[HWTimerID].LoadCount - TIMM0->TIM[HWTimerID].CurrentValue;
  164. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  165. }
  166. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, &HWTimer->Cmd[HWTimer->CurCount]);
  167. HWTimer->CurCount++;
  168. if (OP_QUEUE_CMD_CAPTURE_END != HWTimer->Cmd[HWTimer->CurCount].Operation)
  169. {
  170. return;
  171. }
  172. break;
  173. case OP_QUEUE_CMD_CONTINUE_DELAY:
  174. HWTimer->ContinueDelay = 1;
  175. goto START_HWTIMER;
  176. break;
  177. case OP_QUEUE_CMD_SET_GPIO_DIR_OUT:
  178. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level);
  179. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode > 1)?0:1);
  180. HWTimer->CurCount++;
  181. break;
  182. case OP_QUEUE_CMD_SET_GPIO_DIR_IN:
  183. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode > 1)?0:1);
  184. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 1, 0);
  185. HWTimer->CurCount++;
  186. break;
  187. case OP_QUEUE_CMD_CB:
  188. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, HWTimer->Cmd[HWTimer->CurCount].uParam.pParam);
  189. HWTimer->CurCount++;
  190. break;
  191. case OP_QUEUE_CMD_CAPTURE_SET:
  192. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode > 1)?0:1);
  193. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 1, 0);
  194. TIMM0->TIM[HWTimerID].ControlReg = 0;
  195. TIMM0->TIM[HWTimerID].LoadCount = HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt;
  196. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  197. GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, prvHWTimer_OperationQueuExti, HWTimerID);
  198. prvHWTimer[HWTimerID].ContinueDelay = 0;
  199. switch(HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.ExtiMode)
  200. {
  201. case OP_QUEUE_CMD_IO_EXTI_BOTH:
  202. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 1, 1);
  203. break;
  204. case OP_QUEUE_CMD_IO_EXTI_UP:
  205. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 1, 0);
  206. break;
  207. case OP_QUEUE_CMD_IO_EXTI_DOWN:
  208. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 0, 1);
  209. break;
  210. }
  211. HWTimer->CurCount++;
  212. return;
  213. break;
  214. case OP_QUEUE_CMD_CAPTURE_END:
  215. GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, NULL, NULL);
  216. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 0, 0);
  217. TIMM0->TIM[HWTimerID].ControlReg = 0;
  218. HWTimer->CurCount++;
  219. break;
  220. case OP_QUEUE_CMD_END:
  221. HWTimer->CurCount = 0;
  222. HWTimer->RepeatCnt++;
  223. if (HWTimer->TotalRepeat && (HWTimer->RepeatCnt >= HWTimer->TotalRepeat))
  224. {
  225. TIMM0->TIM[HWTimerID].ControlReg = 0;
  226. TIMM0->TIM[HWTimerID].LoadCount = 24;
  227. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerEndOperationQueue, HWTimerID);
  228. #ifdef __BUILD_OS__
  229. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, IRQ_LOWEST_PRIORITY - 1);
  230. #else
  231. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, 6);
  232. #endif
  233. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  234. return;
  235. }
  236. break;
  237. }
  238. }
  239. return ;
  240. START_HWTIMER:
  241. TIMM0->TIM[HWTimerID].ControlReg = 0;
  242. Period = HWTimer->Cmd[HWTimer->CurCount].uArg.Time;
  243. Period = Period * SYS_TIMER_1US + HWTimer->Cmd[HWTimer->CurCount].PinOrDelay;
  244. TIMM0->TIM[HWTimerID].LoadCount = Period - 1;
  245. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  246. HWTimer->CurCount++;
  247. return ;
  248. }
  249. static void __FUNC_IN_RAM__ prvHWTimer_IrqHandlerOperationQueue( int32_t Line, void *pData)
  250. {
  251. uint32_t HWTimerID = (uint32_t)pData;
  252. volatile uint32_t clr;
  253. clr = TIMM0->TIM[HWTimerID].EOI;
  254. if (!prvHWTimer[HWTimerID].ContinueDelay)
  255. {
  256. TIMM0->TIM[HWTimerID].ControlReg = 0;
  257. }
  258. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], GPIO_NONE);
  259. }
  260. void HWTimer_StartPWM(uint8_t HWTimerID, uint32_t HighCnt, uint32_t LowCnt, uint8_t IsOnePulse)
  261. {
  262. if (!HighCnt) HighCnt = 1;
  263. if (!LowCnt) LowCnt = 1;
  264. TIMM0->TIM[HWTimerID].LoadCount = LowCnt - 1;
  265. TIMM0->TIM_ReloadCount[HWTimerID] = HighCnt - 1;
  266. if (IsOnePulse)
  267. {
  268. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_PWM_SINGLE_PULSE|TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;;
  269. }
  270. else
  271. {
  272. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
  273. }
  274. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
  275. }
  276. void HWTimer_SetPWM(uint8_t HWTimerID, uint32_t Period, uint16_t Duty, uint8_t IsOnePulse)
  277. {
  278. uint32_t TotalCnt;
  279. uint32_t LowCnt, HighCnt;
  280. if (Duty >= 999) return;
  281. if (Period > (SystemCoreClock >> 3)) return;
  282. switch(Period)
  283. {
  284. case 24000000:
  285. LowCnt = 1;
  286. HighCnt = 1;
  287. break;
  288. case 12000000:
  289. LowCnt = 2;
  290. HighCnt = 2;
  291. break;
  292. case 6000000:
  293. LowCnt = 3;
  294. HighCnt = 3;
  295. break;
  296. default:
  297. TotalCnt = (SystemCoreClock >> 2) / Period;
  298. HighCnt = (TotalCnt * Duty) / 1000;
  299. if ((TotalCnt - HighCnt) < 1)
  300. {
  301. LowCnt = 1;
  302. HighCnt = TotalCnt - LowCnt;
  303. }
  304. else
  305. {
  306. LowCnt = TotalCnt - HighCnt;
  307. }
  308. break;
  309. }
  310. HWTimer_StartPWM(HWTimerID, HighCnt, LowCnt, IsOnePulse);
  311. // DBG("L %u, H %u", LowCnt, HighCnt);
  312. // TIMM0->TIM[HWTimerID].LoadCount = LowCnt - 1;
  313. // TIMM0->TIM_ReloadCount[HWTimerID] = HighCnt - 1;
  314. // if (IsOnePulse)
  315. // {
  316. // TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_PWM_SINGLE_PULSE|TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;;
  317. // }
  318. // else
  319. // {
  320. // TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
  321. // }
  322. }
  323. void HWTimer_Stop(uint8_t HWTimerID)
  324. {
  325. volatile uint32_t clr;
  326. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 0);
  327. clr = TIMM0->TIM[HWTimerID].EOI;
  328. TIMM0->TIM[HWTimerID].ControlReg = 0;
  329. ISR_Clear(prvHWTimer[HWTimerID].IrqLine);
  330. prvHWTimer[HWTimerID].IsQueueRunning = 0;
  331. prvHWTimer[HWTimerID].ContinueDelay = 0;
  332. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 0);
  333. }
  334. void HWTimer_InitOperationQueue(uint8_t HWTimerID, uint32_t nCount, uint32_t Repeat, CBFuncEx_t CmdDoneCB, void *pCmdDoneParam)
  335. {
  336. if (prvHWTimer[HWTimerID].IsQueueRunning)
  337. {
  338. HWTimer_Stop(HWTimerID);
  339. prvHWTimer[HWTimerID].CmdDoneCB(-ERROR_OPERATION_FAILED, prvHWTimer[HWTimerID].pCmdDoneParam);
  340. }
  341. prvHWTimer[HWTimerID].TotalCount = nCount;
  342. prvHWTimer[HWTimerID].TotalRepeat = Repeat;
  343. if (prvHWTimer[HWTimerID].Cmd)
  344. {
  345. OS_Free(prvHWTimer[HWTimerID].Cmd);
  346. prvHWTimer[HWTimerID].Cmd = NULL;
  347. }
  348. prvHWTimer[HWTimerID].Cmd = OS_Zalloc((nCount + 1) * sizeof(OPQueue_CmdStruct));
  349. prvHWTimer[HWTimerID].CmdQueuePos = 0;
  350. if (CmdDoneCB)
  351. {
  352. prvHWTimer[HWTimerID].CmdDoneCB = CmdDoneCB;
  353. }
  354. else
  355. {
  356. prvHWTimer[HWTimerID].CmdDoneCB = prvHWTimer_DummyCB;
  357. }
  358. prvHWTimer[HWTimerID].pCmdDoneParam = pCmdDoneParam;
  359. }
  360. void HWTimer_AddOperation(uint8_t HWTimerID, OPQueue_CmdStruct *pCmd)
  361. {
  362. if (prvHWTimer[HWTimerID].TotalCount > prvHWTimer[HWTimerID].CmdQueuePos)
  363. {
  364. memcpy(&prvHWTimer[HWTimerID].Cmd[prvHWTimer[HWTimerID].CmdQueuePos], pCmd, sizeof(OPQueue_CmdStruct));
  365. prvHWTimer[HWTimerID].CmdQueuePos++;
  366. }
  367. }
  368. static void HWTimer_ResetOperationQueue(uint8_t HWTimerID)
  369. {
  370. prvHWTimer[HWTimerID].CurCount = 0;
  371. prvHWTimer[HWTimerID].RepeatCnt = 0;
  372. }
  373. void HWTimer_StartOperationQueue(uint8_t HWTimerID)
  374. {
  375. if (prvHWTimer[HWTimerID].IsQueueRunning)
  376. {
  377. HWTimer_Stop(HWTimerID);
  378. prvHWTimer[HWTimerID].CmdDoneCB(-ERROR_OPERATION_FAILED, prvHWTimer[HWTimerID].pCmdDoneParam);
  379. }
  380. else
  381. {
  382. HWTimer_Stop(HWTimerID);
  383. }
  384. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerOperationQueue, HWTimerID);
  385. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, HWTIMER_IRQ_LEVEL);
  386. prvHWTimer[HWTimerID].Cmd[prvHWTimer[HWTimerID].CmdQueuePos].Operation = OP_QUEUE_CMD_END;
  387. HWTimer_ResetOperationQueue(HWTimerID);
  388. prvHWTimer[HWTimerID].IsQueueRunning = 1;
  389. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], GPIO_NONE);
  390. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 1);
  391. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
  392. }
  393. void HWTimer_ClearOperationQueue(uint8_t HWTimerID)
  394. {
  395. // HWTimer_ResetOperationQueue(HWTimerID);
  396. prvHWTimer[HWTimerID].CmdQueuePos = 0;
  397. }
  398. void HWTimer_FreeOperationQueue(uint8_t HWTimerID)
  399. {
  400. OS_Free(prvHWTimer[HWTimerID].Cmd);
  401. prvHWTimer[HWTimerID].Cmd = NULL;
  402. prvHWTimer[HWTimerID].CmdDoneCB = prvHWTimer_DummyCB;
  403. }
  404. void HWTimer_AddEndCmdInOperationQueue(uint8_t HWTimerID)
  405. {
  406. HWTimer_CtrlStruct *HWTimer = &prvHWTimer[HWTimerID];
  407. if (HWTimer->Cmd[HWTimer->CurCount].Operation != OP_QUEUE_CMD_END)
  408. {
  409. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_END;
  410. }
  411. }
  412. uint8_t HWTimer_CheckOperationQueueDone(uint8_t HWTimerID)
  413. {
  414. return !prvHWTimer[HWTimerID].IsQueueRunning;
  415. }
  416. uint32_t HWTimer_GetOperationQueueCaptureResult(uint8_t HWTimerID, CBFuncEx_t CB, void *pParam)
  417. {
  418. uint32_t i = 0;
  419. uint32_t Cnt = 0;
  420. if (!prvHWTimer[HWTimerID].Cmd) return 0;
  421. for(i = 0; i < prvHWTimer[HWTimerID].CmdQueuePos; i++)
  422. {
  423. if (OP_QUEUE_CMD_CAPTURE == prvHWTimer[HWTimerID].Cmd[i].Operation)
  424. {
  425. CB(&prvHWTimer[HWTimerID].Cmd[i], pParam);
  426. Cnt++;
  427. }
  428. }
  429. return Cnt;
  430. }
  431. uint32_t HWTimer_GetOperationQueueLen(uint8_t HWTimerID)
  432. {
  433. if (!prvHWTimer[HWTimerID].Cmd) return 0;
  434. return prvHWTimer[HWTimerID].CmdQueuePos;
  435. }
  436. OPQueue_CmdStruct *HWTimer_GetOperationQueue(uint8_t HWTimerID)
  437. {
  438. return prvHWTimer[HWTimerID].Cmd;
  439. }