core_hwtimer.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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_IrqHandlerPWM( 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. if ((++prvHWTimer[HWTimerID].CurCount) >= prvHWTimer[HWTimerID].TotalCount)
  438. {
  439. TIMM0->TIM[HWTimerID].ControlReg = 0;
  440. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 0);
  441. ISR_Clear(prvHWTimer[HWTimerID].IrqLine);
  442. prvHWTimer[HWTimerID].IsQueueRunning = 0;
  443. prvHWTimer[HWTimerID].TotalCount = 0;
  444. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 0);
  445. }
  446. else
  447. {
  448. prvHWTimer[HWTimerID].ContinueDelay = 0;
  449. }
  450. }
  451. else
  452. {
  453. prvHWTimer[HWTimerID].ContinueDelay = 1;
  454. }
  455. }
  456. static void __FUNC_IN_RAM__ prvHWTimer_IrqHandlerOperationQueue( int32_t Line, void *pData)
  457. {
  458. uint32_t HWTimerID = (uint32_t)pData;
  459. volatile uint32_t clr;
  460. clr = TIMM0->TIM[HWTimerID].EOI;
  461. if (!prvHWTimer[HWTimerID].ContinueDelay)
  462. {
  463. TIMM0->TIM[HWTimerID].ControlReg = 0;
  464. }
  465. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], GPIO_NONE);
  466. }
  467. void HWTimer_StartPWM(uint8_t HWTimerID, uint32_t HighCnt, uint32_t LowCnt, uint8_t IsOnePulse)
  468. {
  469. if (!HighCnt) HighCnt = 1;
  470. if (!LowCnt) LowCnt = 1;
  471. TIMM0->TIM[HWTimerID].LoadCount = LowCnt - 1;
  472. TIMM0->TIM_ReloadCount[HWTimerID] = HighCnt - 1;
  473. if (IsOnePulse)
  474. {
  475. 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;;
  476. }
  477. else
  478. {
  479. if (prvHWTimer[HWTimerID].TotalCount)
  480. {
  481. // DBG("start %u,%u,%u",TIMM0->TIM[HWTimerID].LoadCount, TIMM0->TIM_ReloadCount[HWTimerID], prvHWTimer[HWTimerID].TotalCount);
  482. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerPWM, HWTimerID);
  483. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, HWTIMER_IRQ_LEVEL);
  484. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 1);
  485. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE;
  486. }
  487. else
  488. {
  489. TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
  490. }
  491. }
  492. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
  493. }
  494. void HWTimer_SetPWM(uint8_t HWTimerID, uint32_t Period, uint16_t Duty, uint32_t PulseNum)
  495. {
  496. uint32_t TotalCnt;
  497. uint32_t LowCnt, HighCnt;
  498. if (Duty >= 999) return;
  499. if (Period > (SystemCoreClock >> 3)) return;
  500. switch(Period)
  501. {
  502. case 24000000:
  503. LowCnt = 1;
  504. HighCnt = 1;
  505. break;
  506. case 12000000:
  507. LowCnt = 2;
  508. HighCnt = 2;
  509. break;
  510. case 6000000:
  511. LowCnt = 3;
  512. HighCnt = 3;
  513. break;
  514. default:
  515. TotalCnt = (SystemCoreClock >> 2) / Period;
  516. HighCnt = (TotalCnt * Duty) / 1000;
  517. if ((TotalCnt - HighCnt) < 1)
  518. {
  519. LowCnt = 1;
  520. HighCnt = TotalCnt - LowCnt;
  521. }
  522. else
  523. {
  524. LowCnt = TotalCnt - HighCnt;
  525. }
  526. break;
  527. }
  528. prvHWTimer[HWTimerID].TotalCount = PulseNum;
  529. prvHWTimer[HWTimerID].CurCount = 0;
  530. prvHWTimer[HWTimerID].ContinueDelay = 0;
  531. HWTimer_StartPWM(HWTimerID, HighCnt, LowCnt, 0);
  532. // DBG("L %u, H %u", LowCnt, HighCnt);
  533. // TIMM0->TIM[HWTimerID].LoadCount = LowCnt - 1;
  534. // TIMM0->TIM_ReloadCount[HWTimerID] = HighCnt - 1;
  535. // if (IsOnePulse)
  536. // {
  537. // 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;;
  538. // }
  539. // else
  540. // {
  541. // TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
  542. // }
  543. }
  544. void HWTimer_Stop(uint8_t HWTimerID)
  545. {
  546. volatile uint32_t clr;
  547. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 0);
  548. clr = TIMM0->TIM[HWTimerID].EOI;
  549. TIMM0->TIM[HWTimerID].ControlReg = 0;
  550. ISR_Clear(prvHWTimer[HWTimerID].IrqLine);
  551. prvHWTimer[HWTimerID].IsQueueRunning = 0;
  552. prvHWTimer[HWTimerID].ContinueDelay = 0;
  553. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 0);
  554. }
  555. void HWTimer_InitOperationQueue(uint8_t HWTimerID, uint32_t nCount, uint32_t Repeat, CBFuncEx_t CmdDoneCB, void *pCmdDoneParam)
  556. {
  557. if (prvHWTimer[HWTimerID].IsQueueRunning)
  558. {
  559. HWTimer_Stop(HWTimerID);
  560. prvHWTimer[HWTimerID].CmdDoneCB(-ERROR_OPERATION_FAILED, prvHWTimer[HWTimerID].pCmdDoneParam);
  561. }
  562. prvHWTimer[HWTimerID].TotalCount = nCount;
  563. prvHWTimer[HWTimerID].TotalRepeat = Repeat;
  564. if (prvHWTimer[HWTimerID].Cmd)
  565. {
  566. OS_Free(prvHWTimer[HWTimerID].Cmd);
  567. prvHWTimer[HWTimerID].Cmd = NULL;
  568. }
  569. prvHWTimer[HWTimerID].Cmd = OS_Zalloc((nCount + 1) * sizeof(OPQueue_CmdStruct));
  570. prvHWTimer[HWTimerID].CmdQueuePos = 0;
  571. if (CmdDoneCB)
  572. {
  573. prvHWTimer[HWTimerID].CmdDoneCB = CmdDoneCB;
  574. }
  575. else
  576. {
  577. prvHWTimer[HWTimerID].CmdDoneCB = prvHWTimer_DummyCB;
  578. }
  579. prvHWTimer[HWTimerID].pCmdDoneParam = pCmdDoneParam;
  580. }
  581. void HWTimer_AddOperation(uint8_t HWTimerID, OPQueue_CmdStruct *pCmd)
  582. {
  583. if (prvHWTimer[HWTimerID].TotalCount > prvHWTimer[HWTimerID].CmdQueuePos)
  584. {
  585. memcpy(&prvHWTimer[HWTimerID].Cmd[prvHWTimer[HWTimerID].CmdQueuePos], pCmd, sizeof(OPQueue_CmdStruct));
  586. prvHWTimer[HWTimerID].CmdQueuePos++;
  587. }
  588. }
  589. static void HWTimer_ResetOperationQueue(uint8_t HWTimerID)
  590. {
  591. prvHWTimer[HWTimerID].CurCount = 0;
  592. prvHWTimer[HWTimerID].RepeatCnt = 0;
  593. }
  594. void HWTimer_StartOperationQueue(uint8_t HWTimerID)
  595. {
  596. if (prvHWTimer[HWTimerID].IsQueueRunning)
  597. {
  598. HWTimer_Stop(HWTimerID);
  599. prvHWTimer[HWTimerID].CmdDoneCB(-ERROR_OPERATION_FAILED, prvHWTimer[HWTimerID].pCmdDoneParam);
  600. }
  601. else
  602. {
  603. HWTimer_Stop(HWTimerID);
  604. }
  605. ISR_SetHandler(prvHWTimer[HWTimerID].IrqLine, prvHWTimer_IrqHandlerOperationQueue, HWTimerID);
  606. ISR_SetPriority(prvHWTimer[HWTimerID].IrqLine, HWTIMER_IRQ_LEVEL);
  607. prvHWTimer[HWTimerID].Cmd[prvHWTimer[HWTimerID].CmdQueuePos].Operation = OP_QUEUE_CMD_END;
  608. HWTimer_ResetOperationQueue(HWTimerID);
  609. prvHWTimer[HWTimerID].IsQueueRunning = 1;
  610. prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID], GPIO_NONE);
  611. ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 1);
  612. PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
  613. }
  614. void HWTimer_ClearOperationQueue(uint8_t HWTimerID)
  615. {
  616. // HWTimer_ResetOperationQueue(HWTimerID);
  617. prvHWTimer[HWTimerID].CmdQueuePos = 0;
  618. }
  619. void HWTimer_FreeOperationQueue(uint8_t HWTimerID)
  620. {
  621. OS_Free(prvHWTimer[HWTimerID].Cmd);
  622. prvHWTimer[HWTimerID].Cmd = NULL;
  623. prvHWTimer[HWTimerID].CmdDoneCB = prvHWTimer_DummyCB;
  624. }
  625. void HWTimer_AddEndCmdInOperationQueue(uint8_t HWTimerID)
  626. {
  627. HWTimer_CtrlStruct *HWTimer = &prvHWTimer[HWTimerID];
  628. if (HWTimer->Cmd[HWTimer->CurCount].Operation != OP_QUEUE_CMD_END)
  629. {
  630. HWTimer->Cmd[HWTimer->CurCount + 1].Operation = OP_QUEUE_CMD_END;
  631. }
  632. }
  633. uint8_t HWTimer_CheckOperationQueueDone(uint8_t HWTimerID)
  634. {
  635. return !prvHWTimer[HWTimerID].IsQueueRunning;
  636. }
  637. uint32_t HWTimer_GetOperationQueueCaptureResult(uint8_t HWTimerID, CBFuncEx_t CB, void *pParam)
  638. {
  639. uint32_t i = 0;
  640. uint32_t Cnt = 0;
  641. if (!prvHWTimer[HWTimerID].Cmd) return 0;
  642. for(i = 0; i < prvHWTimer[HWTimerID].CmdQueuePos; i++)
  643. {
  644. if (OP_QUEUE_CMD_CAPTURE == prvHWTimer[HWTimerID].Cmd[i].Operation)
  645. {
  646. CB(&prvHWTimer[HWTimerID].Cmd[i], pParam);
  647. Cnt++;
  648. }
  649. }
  650. return Cnt;
  651. }
  652. uint32_t HWTimer_GetOperationQueueLen(uint8_t HWTimerID)
  653. {
  654. if (!prvHWTimer[HWTimerID].Cmd) return 0;
  655. return prvHWTimer[HWTimerID].CmdQueuePos;
  656. }
  657. OPQueue_CmdStruct *HWTimer_GetOperationQueue(uint8_t HWTimerID)
  658. {
  659. return prvHWTimer[HWTimerID].Cmd;
  660. }