core_hwtimer.c 23 KB

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