core_hwtimer.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  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. typedef int (*queue_fun)(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin);
  106. #define OPERATION_GO_ON (0)
  107. #define OPERATION_OUT_IRQ (-1)
  108. #define OPERATION_RESET_TIMER (1)
  109. static int __FUNC_IN_RAM__ prvHWTimer_OperationEnd(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  110. {
  111. HWTimer->CurCount = 0;
  112. HWTimer->RepeatCnt++;
  113. if (HWTimer->TotalRepeat && (HWTimer->RepeatCnt >= HWTimer->TotalRepeat))
  114. {
  115. TIMM0->TIM[HWTimerID].ControlReg = 0;
  116. TIMM0->TIM[HWTimerID].LoadCount = 24;
  117. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerEndOperationQueue, HWTimerID);
  118. #ifdef __BUILD_OS__
  119. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, IRQ_LOWEST_PRIORITY - 1);
  120. #else
  121. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, 6);
  122. #endif
  123. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  124. return OPERATION_OUT_IRQ;
  125. }
  126. else
  127. {
  128. return OPERATION_GO_ON;
  129. }
  130. }
  131. static int __FUNC_IN_RAM__ prvHWTimer_OperationDelayOnce(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  132. {
  133. HWTimer->ContinueDelay = 0;
  134. return OPERATION_RESET_TIMER;
  135. }
  136. static int __FUNC_IN_RAM__ prvHWTimer_OperationDelay(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  137. {
  138. HWTimer->ContinueDelay = 1;
  139. return OPERATION_RESET_TIMER;
  140. }
  141. static int __FUNC_IN_RAM__ prvHWTimer_OperationRepeatDelay(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  142. {
  143. HWTimer->CurCount++;
  144. return OPERATION_OUT_IRQ;
  145. }
  146. static int __FUNC_IN_RAM__ prvHWTimer_OperationSetGPIOOut(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  147. {
  148. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level);
  149. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode > 1)?0:1);
  150. HWTimer->CurCount++;
  151. return OPERATION_GO_ON;
  152. }
  153. static int __FUNC_IN_RAM__ prvHWTimer_OperationSetGPIOIn(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  154. {
  155. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode > 1)?0:1);
  156. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 1, 0);
  157. HWTimer->CurCount++;
  158. return OPERATION_GO_ON;
  159. }
  160. static int __FUNC_IN_RAM__ prvHWTimer_OperationGPIOOut(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  161. {
  162. GPIO_Output(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level);
  163. HWTimer->CurCount++;
  164. return OPERATION_GO_ON;
  165. }
  166. static int __FUNC_IN_RAM__ prvHWTimer_OperationGPIOIn(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  167. {
  168. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  169. HWTimer->CurCount++;
  170. return OPERATION_GO_ON;
  171. }
  172. static int __FUNC_IN_RAM__ prvHWTimer_OperationGPIOInCB(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  173. {
  174. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  175. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, &HWTimer->Cmd[HWTimer->CurCount]);
  176. HWTimer->CurCount++;
  177. return OPERATION_GO_ON;
  178. }
  179. static int __FUNC_IN_RAM__ prvHWTimer_OperationCB(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  180. {
  181. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, HWTimer->Cmd[HWTimer->CurCount].uParam.pParam);
  182. HWTimer->CurCount++;
  183. return OPERATION_GO_ON;
  184. }
  185. static int __FUNC_IN_RAM__ prvHWTimer_OperationCaptureSet(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  186. {
  187. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode > 1)?0:1);
  188. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 1, 0);
  189. TIMM0->TIM[HWTimerID].ControlReg = 0;
  190. TIMM0->TIM[HWTimerID].LoadCount = HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt;
  191. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  192. GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, prvHWTimer_OperationQueuExti, HWTimerID);
  193. prvHWTimer[HWTimerID].ContinueDelay = 0;
  194. switch(HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.ExtiMode)
  195. {
  196. case OP_QUEUE_CMD_IO_EXTI_BOTH:
  197. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 1, 1);
  198. break;
  199. case OP_QUEUE_CMD_IO_EXTI_UP:
  200. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 1, 0);
  201. break;
  202. case OP_QUEUE_CMD_IO_EXTI_DOWN:
  203. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 0, 1);
  204. break;
  205. }
  206. HWTimer->CurCount++;
  207. return OPERATION_OUT_IRQ;
  208. }
  209. static int __FUNC_IN_RAM__ prvHWTimer_OperationCapture(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  210. {
  211. HWTimer->Cmd[HWTimer->CurCount].PinOrDelay = Pin;
  212. if (!TIMM0->TIM[HWTimerID].ControlReg)
  213. {
  214. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_CAPTURE_END;
  215. }
  216. else
  217. {
  218. HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt = TIMM0->TIM[HWTimerID].LoadCount - TIMM0->TIM[HWTimerID].CurrentValue;
  219. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  220. }
  221. HWTimer->CurCount++;
  222. if (OP_QUEUE_CMD_CAPTURE_END != HWTimer->Cmd[HWTimer->CurCount].Operation)
  223. {
  224. return OPERATION_OUT_IRQ;
  225. }
  226. return OPERATION_GO_ON;
  227. }
  228. static int __FUNC_IN_RAM__ prvHWTimer_OperationCaptureCB(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  229. {
  230. HWTimer->Cmd[HWTimer->CurCount].PinOrDelay = Pin;
  231. if (!TIMM0->TIM[HWTimerID].ControlReg)
  232. {
  233. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_CAPTURE_END;
  234. }
  235. else
  236. {
  237. HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt = TIMM0->TIM[HWTimerID].LoadCount - TIMM0->TIM[HWTimerID].CurrentValue;
  238. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  239. }
  240. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, &HWTimer->Cmd[HWTimer->CurCount]);
  241. HWTimer->CurCount++;
  242. if (OP_QUEUE_CMD_CAPTURE_END != HWTimer->Cmd[HWTimer->CurCount].Operation)
  243. {
  244. return OPERATION_OUT_IRQ;
  245. }
  246. return OPERATION_GO_ON;
  247. }
  248. static int __FUNC_IN_RAM__ prvHWTimer_OperationCaptureEnd(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  249. {
  250. GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, NULL, NULL);
  251. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 0, 0);
  252. TIMM0->TIM[HWTimerID].ControlReg = 0;
  253. HWTimer->CurCount++;
  254. return OPERATION_GO_ON;
  255. }
  256. static queue_fun queueFunlist[] =
  257. {
  258. prvHWTimer_OperationEnd,
  259. prvHWTimer_OperationDelayOnce, //只有一次delay
  260. prvHWTimer_OperationDelay, //连续delay,配合OP_QUEUE_CMD_REPEAT_DELAY使用
  261. prvHWTimer_OperationRepeatDelay, //重复OP_QUEUE_CMD_CONTINUE_DELAY
  262. prvHWTimer_OperationSetGPIOOut,
  263. prvHWTimer_OperationSetGPIOIn,
  264. prvHWTimer_OperationGPIOOut,
  265. prvHWTimer_OperationGPIOIn,
  266. prvHWTimer_OperationGPIOInCB,
  267. prvHWTimer_OperationCB,
  268. prvHWTimer_OperationCaptureSet,
  269. prvHWTimer_OperationCapture,
  270. prvHWTimer_OperationCaptureCB,
  271. prvHWTimer_OperationCaptureEnd,
  272. };
  273. static void __FUNC_IN_RAM__ prvHWTimer_StartOperationQueue(uint8_t HWTimerID, HWTimer_CtrlStruct *HWTimer, uint8_t Pin)
  274. {
  275. volatile uint32_t Period;
  276. int result;
  277. while(HWTimer->IsQueueRunning)
  278. {
  279. // DBG("%u,%u,%u,%u,%u,%u,%u,%u,%u,%x", HWTimer->TotalRepeat, HWTimer->RepeatCnt,
  280. // HWTimer->TotalCount, HWTimer->CurCount, HWTimer->Cmd[HWTimer->CurCount].Operation,
  281. // HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level,
  282. // HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, HWTimer->Cmd[HWTimer->CurCount].uArg.Time,
  283. // HWTimer->Cmd[HWTimer->CurCount].CB);
  284. #if 1
  285. result = queueFunlist[HWTimer->Cmd[HWTimer->CurCount].Operation](HWTimerID, HWTimer, Pin);
  286. switch(result)
  287. {
  288. case OPERATION_OUT_IRQ:
  289. return;
  290. case OPERATION_RESET_TIMER:
  291. goto START_HWTIMER;
  292. break;
  293. }
  294. #else
  295. switch(HWTimer->Cmd[HWTimer->CurCount].Operation)
  296. {
  297. case OP_QUEUE_CMD_GPIO_OUT:
  298. GPIO_Output(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level);
  299. HWTimer->CurCount++;
  300. break;
  301. case OP_QUEUE_CMD_GPIO_IN_CB:
  302. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  303. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, &HWTimer->Cmd[HWTimer->CurCount]);
  304. HWTimer->CurCount++;
  305. break;
  306. case OP_QUEUE_CMD_GPIO_IN:
  307. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  308. HWTimer->CurCount++;
  309. break;
  310. case OP_QUEUE_CMD_ONE_TIME_DELAY:
  311. HWTimer->ContinueDelay = 0;
  312. goto START_HWTIMER;
  313. break;
  314. case OP_QUEUE_CMD_REPEAT_DELAY:
  315. HWTimer->CurCount++;
  316. return;
  317. break;
  318. case OP_QUEUE_CMD_CAPTURE:
  319. HWTimer->Cmd[HWTimer->CurCount].PinOrDelay = Pin;
  320. if (!TIMM0->TIM[HWTimerID].ControlReg)
  321. {
  322. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_CAPTURE_END;
  323. }
  324. else
  325. {
  326. HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt = TIMM0->TIM[HWTimerID].LoadCount - TIMM0->TIM[HWTimerID].CurrentValue;
  327. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  328. }
  329. HWTimer->CurCount++;
  330. if (OP_QUEUE_CMD_CAPTURE_END != HWTimer->Cmd[HWTimer->CurCount].Operation)
  331. {
  332. return;
  333. }
  334. break;
  335. case OP_QUEUE_CMD_CAPTURE_CB:
  336. HWTimer->Cmd[HWTimer->CurCount].PinOrDelay = Pin;
  337. if (!TIMM0->TIM[HWTimerID].ControlReg)
  338. {
  339. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_CAPTURE_END;
  340. }
  341. else
  342. {
  343. HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt = TIMM0->TIM[HWTimerID].LoadCount - TIMM0->TIM[HWTimerID].CurrentValue;
  344. HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level = GPIO_Input(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay);
  345. }
  346. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, &HWTimer->Cmd[HWTimer->CurCount]);
  347. HWTimer->CurCount++;
  348. if (OP_QUEUE_CMD_CAPTURE_END != HWTimer->Cmd[HWTimer->CurCount].Operation)
  349. {
  350. return;
  351. }
  352. break;
  353. case OP_QUEUE_CMD_CONTINUE_DELAY:
  354. HWTimer->ContinueDelay = 1;
  355. goto START_HWTIMER;
  356. break;
  357. case OP_QUEUE_CMD_SET_GPIO_DIR_OUT:
  358. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.Level);
  359. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode > 1)?0:1);
  360. HWTimer->CurCount++;
  361. break;
  362. case OP_QUEUE_CMD_SET_GPIO_DIR_IN:
  363. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.IOArg.PullMode > 1)?0:1);
  364. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 1, 0);
  365. HWTimer->CurCount++;
  366. break;
  367. case OP_QUEUE_CMD_CB:
  368. HWTimer->Cmd[HWTimer->CurCount].CB(HWTimerID, HWTimer->Cmd[HWTimer->CurCount].uParam.pParam);
  369. HWTimer->CurCount++;
  370. break;
  371. case OP_QUEUE_CMD_CAPTURE_SET:
  372. GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode > 1)?0:1);
  373. GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 1, 0);
  374. TIMM0->TIM[HWTimerID].ControlReg = 0;
  375. TIMM0->TIM[HWTimerID].LoadCount = HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt;
  376. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  377. GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, prvHWTimer_OperationQueuExti, HWTimerID);
  378. prvHWTimer[HWTimerID].ContinueDelay = 0;
  379. switch(HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.ExtiMode)
  380. {
  381. case OP_QUEUE_CMD_IO_EXTI_BOTH:
  382. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 1, 1);
  383. break;
  384. case OP_QUEUE_CMD_IO_EXTI_UP:
  385. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 1, 0);
  386. break;
  387. case OP_QUEUE_CMD_IO_EXTI_DOWN:
  388. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 0, 1);
  389. break;
  390. }
  391. HWTimer->CurCount++;
  392. return;
  393. break;
  394. case OP_QUEUE_CMD_CAPTURE_END:
  395. GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, NULL, NULL);
  396. GPIO_ExtiConfig(HWTimer->Cmd[HWTimer->CurCount].PinOrDelay, 0, 0, 0);
  397. TIMM0->TIM[HWTimerID].ControlReg = 0;
  398. HWTimer->CurCount++;
  399. break;
  400. case OP_QUEUE_CMD_END:
  401. HWTimer->CurCount = 0;
  402. HWTimer->RepeatCnt++;
  403. if (HWTimer->TotalRepeat && (HWTimer->RepeatCnt >= HWTimer->TotalRepeat))
  404. {
  405. TIMM0->TIM[HWTimerID].ControlReg = 0;
  406. TIMM0->TIM[HWTimerID].LoadCount = 24;
  407. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerEndOperationQueue, HWTimerID);
  408. #ifdef __BUILD_OS__
  409. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, IRQ_LOWEST_PRIORITY - 1);
  410. #else
  411. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, 6);
  412. #endif
  413. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  414. return;
  415. }
  416. break;
  417. }
  418. #endif
  419. }
  420. return ;
  421. START_HWTIMER:
  422. TIMM0->TIM[HWTimerID].ControlReg = 0;
  423. Period = HWTimer->Cmd[HWTimer->CurCount].uArg.Time;
  424. Period = Period * SYS_TIMER_1US + HWTimer->Cmd[HWTimer->CurCount].PinOrDelay;
  425. TIMM0->TIM[HWTimerID].LoadCount = Period - 1;
  426. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  427. HWTimer->CurCount++;
  428. return ;
  429. }
  430. static void __FUNC_IN_RAM__ prvHWTimer_IrqHandlerOperationQueue( int32_t Line, void *pData)
  431. {
  432. uint32_t HWTimerID = (uint32_t)pData;
  433. volatile uint32_t clr;
  434. clr = TIMM0->TIM[HWTimerID].EOI;
  435. if (!prvHWTimer[HWTimerID].ContinueDelay)
  436. {
  437. TIMM0->TIM[HWTimerID].ControlReg = 0;
  438. }
  439. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], GPIO_NONE);
  440. }
  441. void HWTimer_StartPWM(uint8_t HWTimerID, uint32_t HighCnt, uint32_t LowCnt, uint8_t IsOnePulse)
  442. {
  443. if (!HighCnt) HighCnt = 1;
  444. if (!LowCnt) LowCnt = 1;
  445. TIMM0->TIM[HWTimerID].LoadCount = LowCnt - 1;
  446. TIMM0->TIM_ReloadCount[HWTimerID] = HighCnt - 1;
  447. if (IsOnePulse)
  448. {
  449. 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;;
  450. }
  451. else
  452. {
  453. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
  454. }
  455. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
  456. }
  457. void HWTimer_SetPWM(uint8_t HWTimerID, uint32_t Period, uint16_t Duty, uint8_t IsOnePulse)
  458. {
  459. uint32_t TotalCnt;
  460. uint32_t LowCnt, HighCnt;
  461. if (Duty >= 999) return;
  462. if (Period > (SystemCoreClock >> 3)) return;
  463. switch(Period)
  464. {
  465. case 24000000:
  466. LowCnt = 1;
  467. HighCnt = 1;
  468. break;
  469. case 12000000:
  470. LowCnt = 2;
  471. HighCnt = 2;
  472. break;
  473. case 6000000:
  474. LowCnt = 3;
  475. HighCnt = 3;
  476. break;
  477. default:
  478. TotalCnt = (SystemCoreClock >> 2) / Period;
  479. HighCnt = (TotalCnt * Duty) / 1000;
  480. if ((TotalCnt - HighCnt) < 1)
  481. {
  482. LowCnt = 1;
  483. HighCnt = TotalCnt - LowCnt;
  484. }
  485. else
  486. {
  487. LowCnt = TotalCnt - HighCnt;
  488. }
  489. break;
  490. }
  491. HWTimer_StartPWM(HWTimerID, HighCnt, LowCnt, IsOnePulse);
  492. // DBG("L %u, H %u", LowCnt, HighCnt);
  493. // TIMM0->TIM[HWTimerID].LoadCount = LowCnt - 1;
  494. // TIMM0->TIM_ReloadCount[HWTimerID] = HighCnt - 1;
  495. // if (IsOnePulse)
  496. // {
  497. // 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;;
  498. // }
  499. // else
  500. // {
  501. // TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
  502. // }
  503. }
  504. void HWTimer_Stop(uint8_t HWTimerID)
  505. {
  506. volatile uint32_t clr;
  507. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 0);
  508. clr = TIMM0->TIM[HWTimerID].EOI;
  509. TIMM0->TIM[HWTimerID].ControlReg = 0;
  510. ISR_Clear(prvHWTimer[HWTimerID].IrqLine);
  511. prvHWTimer[HWTimerID].IsQueueRunning = 0;
  512. prvHWTimer[HWTimerID].ContinueDelay = 0;
  513. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 0);
  514. }
  515. void HWTimer_InitOperationQueue(uint8_t HWTimerID, uint32_t nCount, uint32_t Repeat, CBFuncEx_t CmdDoneCB, void *pCmdDoneParam)
  516. {
  517. if (prvHWTimer[HWTimerID].IsQueueRunning)
  518. {
  519. HWTimer_Stop(HWTimerID);
  520. prvHWTimer[HWTimerID].CmdDoneCB(-ERROR_OPERATION_FAILED, prvHWTimer[HWTimerID].pCmdDoneParam);
  521. }
  522. prvHWTimer[HWTimerID].TotalCount = nCount;
  523. prvHWTimer[HWTimerID].TotalRepeat = Repeat;
  524. if (prvHWTimer[HWTimerID].Cmd)
  525. {
  526. OS_Free(prvHWTimer[HWTimerID].Cmd);
  527. prvHWTimer[HWTimerID].Cmd = NULL;
  528. }
  529. prvHWTimer[HWTimerID].Cmd = OS_Zalloc((nCount + 1) * sizeof(OPQueue_CmdStruct));
  530. prvHWTimer[HWTimerID].CmdQueuePos = 0;
  531. if (CmdDoneCB)
  532. {
  533. prvHWTimer[HWTimerID].CmdDoneCB = CmdDoneCB;
  534. }
  535. else
  536. {
  537. prvHWTimer[HWTimerID].CmdDoneCB = prvHWTimer_DummyCB;
  538. }
  539. prvHWTimer[HWTimerID].pCmdDoneParam = pCmdDoneParam;
  540. }
  541. void HWTimer_AddOperation(uint8_t HWTimerID, OPQueue_CmdStruct *pCmd)
  542. {
  543. if (prvHWTimer[HWTimerID].TotalCount > prvHWTimer[HWTimerID].CmdQueuePos)
  544. {
  545. memcpy(&prvHWTimer[HWTimerID].Cmd[prvHWTimer[HWTimerID].CmdQueuePos], pCmd, sizeof(OPQueue_CmdStruct));
  546. prvHWTimer[HWTimerID].CmdQueuePos++;
  547. }
  548. }
  549. static void HWTimer_ResetOperationQueue(uint8_t HWTimerID)
  550. {
  551. prvHWTimer[HWTimerID].CurCount = 0;
  552. prvHWTimer[HWTimerID].RepeatCnt = 0;
  553. }
  554. void HWTimer_StartOperationQueue(uint8_t HWTimerID)
  555. {
  556. if (prvHWTimer[HWTimerID].IsQueueRunning)
  557. {
  558. HWTimer_Stop(HWTimerID);
  559. prvHWTimer[HWTimerID].CmdDoneCB(-ERROR_OPERATION_FAILED, prvHWTimer[HWTimerID].pCmdDoneParam);
  560. }
  561. else
  562. {
  563. HWTimer_Stop(HWTimerID);
  564. }
  565. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerOperationQueue, HWTimerID);
  566. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, HWTIMER_IRQ_LEVEL);
  567. prvHWTimer[HWTimerID].Cmd[prvHWTimer[HWTimerID].CmdQueuePos].Operation = OP_QUEUE_CMD_END;
  568. HWTimer_ResetOperationQueue(HWTimerID);
  569. prvHWTimer[HWTimerID].IsQueueRunning = 1;
  570. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], GPIO_NONE);
  571. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 1);
  572. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
  573. }
  574. void HWTimer_ClearOperationQueue(uint8_t HWTimerID)
  575. {
  576. // HWTimer_ResetOperationQueue(HWTimerID);
  577. prvHWTimer[HWTimerID].CmdQueuePos = 0;
  578. }
  579. void HWTimer_FreeOperationQueue(uint8_t HWTimerID)
  580. {
  581. OS_Free(prvHWTimer[HWTimerID].Cmd);
  582. prvHWTimer[HWTimerID].Cmd = NULL;
  583. prvHWTimer[HWTimerID].CmdDoneCB = prvHWTimer_DummyCB;
  584. }
  585. void HWTimer_AddEndCmdInOperationQueue(uint8_t HWTimerID)
  586. {
  587. HWTimer_CtrlStruct *HWTimer = &prvHWTimer[HWTimerID];
  588. if (HWTimer->Cmd[HWTimer->CurCount].Operation != OP_QUEUE_CMD_END)
  589. {
  590. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_END;
  591. }
  592. }
  593. uint8_t HWTimer_CheckOperationQueueDone(uint8_t HWTimerID)
  594. {
  595. return !prvHWTimer[HWTimerID].IsQueueRunning;
  596. }
  597. uint32_t HWTimer_GetOperationQueueCaptureResult(uint8_t HWTimerID, CBFuncEx_t CB, void *pParam)
  598. {
  599. uint32_t i = 0;
  600. uint32_t Cnt = 0;
  601. if (!prvHWTimer[HWTimerID].Cmd) return 0;
  602. for(i = 0; i < prvHWTimer[HWTimerID].CmdQueuePos; i++)
  603. {
  604. if (OP_QUEUE_CMD_CAPTURE == prvHWTimer[HWTimerID].Cmd[i].Operation)
  605. {
  606. CB(&prvHWTimer[HWTimerID].Cmd[i], pParam);
  607. Cnt++;
  608. }
  609. }
  610. return Cnt;
  611. }
  612. uint32_t HWTimer_GetOperationQueueLen(uint8_t HWTimerID)
  613. {
  614. if (!prvHWTimer[HWTimerID].Cmd) return 0;
  615. return prvHWTimer[HWTimerID].CmdQueuePos;
  616. }
  617. OPQueue_CmdStruct *HWTimer_GetOperationQueue(uint8_t HWTimerID)
  618. {
  619. return prvHWTimer[HWTimerID].Cmd;
  620. }