ftimer.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: ftimer.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-02-18 09:09:49
  17. * Description:  This files is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. */
  23. /***************************** Include Files *********************************/
  24. #include <string.h>
  25. #include "fassert.h"
  26. #include "ftimer_tacho_hw.h"
  27. #include "ftimer_tacho.h"
  28. /************************** Function Prototypes ******************************/
  29. /**
  30. * @name: FTimerSoftwareReset
  31. * @msg: 将控制器复位
  32. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  33. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  34. */
  35. FError FTimerSoftwareReset(FTimerTachoCtrl *instance_p)
  36. {
  37. FASSERT(instance_p);
  38. if (instance_p->isready != FT_COMPONENT_IS_READY)
  39. {
  40. FTIMER_ERROR("device is not already!!!");
  41. return FTIMER_TACHO_ERR_NOT_READY;
  42. }
  43. u32 reg_val = FTIMER_CTRL_READ(instance_p);
  44. u32 Timeout = 0;
  45. reg_val |= FTIMER_REG_TACHO_RESET;
  46. FTIMER_CTRL_WRITE(instance_p, reg_val);
  47. do
  48. {
  49. reg_val = FTIMER_CTRL_READ(instance_p);
  50. Timeout++;
  51. }
  52. while ((reg_val & FTIMER_REG_TACHO_RESET) && (Timeout < FTIMER_TIMEOUT));
  53. if (Timeout >= FTIMER_TIMEOUT)
  54. {
  55. FTIMER_ERROR("Software Reset Failed!!!");
  56. return FTIMER_TACHO_ERR_FAILED;
  57. }
  58. return FTIMER_TACHO_SUCCESS;
  59. }
  60. /**
  61. * @name: FTimerStart
  62. * @msg: 启动timer_tacho外设,根据不同的功能,开启使能位
  63. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  64. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  65. */
  66. FError FTimerStart(FTimerTachoCtrl *instance_p)
  67. {
  68. FASSERT(instance_p);
  69. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  70. u32 reg_val;
  71. reg_val = FTIMER_CTRL_READ(instance_p);
  72. if (FTIMER_WORK_MODE_TIMER == instance_p->config.work_mode)
  73. {
  74. reg_val |= FTIMER_REG_ENABLE;
  75. }
  76. else
  77. {
  78. /* for tacho mode and capture mode */
  79. reg_val |= FTIMER_REG_ENABLE | FTACHO_REG_CAP_IN_ENABLE;
  80. }
  81. FTIMER_CTRL_WRITE(instance_p, reg_val);
  82. return FTIMER_TACHO_SUCCESS;
  83. }
  84. /**
  85. * @name: FTimerStop
  86. * @msg: 停止timer外设,根据不同的功能,关闭使能位,计数值停止并冻结
  87. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  88. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  89. */
  90. FError FTimerStop(FTimerTachoCtrl *instance_p)
  91. {
  92. FASSERT(instance_p);
  93. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  94. u32 reg_val = FTIMER_CTRL_READ(instance_p);
  95. if (FTIMER_WORK_MODE_TIMER == instance_p->config.work_mode)
  96. {
  97. reg_val &= (~FTIMER_REG_ENABLE);
  98. }
  99. else
  100. {
  101. /* for tacho mode and capture mode */
  102. reg_val &= (~FTIMER_REG_ENABLE) & (~FTACHO_REG_CAP_IN_ENABLE);
  103. }
  104. FTIMER_CTRL_WRITE(instance_p, reg_val);
  105. return FTIMER_TACHO_SUCCESS;
  106. }
  107. /**
  108. * @name: TimerSwithBits
  109. * @msg: 计数器32/64切换
  110. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  111. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  112. */
  113. static FError TimerSwithBits(FTimerTachoCtrl *instance_p)
  114. {
  115. u32 reg_val;
  116. FASSERT(instance_p);
  117. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  118. reg_val = FTIMER_CTRL_READ(instance_p);
  119. if (FTIMER_32_BITS == instance_p->config.timer_bits)
  120. {
  121. reg_val &= (~FTIMER_REG_CNT_SERIES_64BIT);
  122. }
  123. else if (FTIMER_64_BITS == instance_p->config.timer_bits)
  124. {
  125. reg_val |= FTIMER_REG_CNT_SERIES_64BIT;
  126. }
  127. else
  128. {
  129. FTIMER_ERROR("invalid input");
  130. return FTIMER_TACHO_ERR_INVAL_PARM;
  131. }
  132. FTIMER_CTRL_WRITE(instance_p, reg_val);
  133. return FTIMER_TACHO_SUCCESS;
  134. }
  135. /**
  136. * @name: TimerForceLoad
  137. * @msg: 强制更新位置位
  138. * @return {void} 无
  139. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  140. */
  141. static void TimerForceLoad(FTimerTachoCtrl *instance_p)
  142. {
  143. u32 reg_val;
  144. FASSERT(instance_p);
  145. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  146. reg_val = FTIMER_CTRL_READ(instance_p);
  147. reg_val |= FTIMER_REG_TACHO_FORCE_LOAD;
  148. FTIMER_CTRL_WRITE(instance_p, reg_val);
  149. return;
  150. }
  151. /**
  152. * @name: FTimerSetPeriod32
  153. * @msg: 设置32位计数模式下,计数器的compare的值,达到此值,如果开启中断,则开启中断
  154. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  155. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  156. * @param {u32}NewCmpL
  157. */
  158. FError FTimerSetPeriod32(FTimerTachoCtrl *instance_p, u32 new_cmp_l)
  159. {
  160. FASSERT(instance_p);
  161. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  162. if (FTIMER_64_BITS == instance_p->config.timer_bits)
  163. {
  164. return FTIMER_TACHO_ERR_INVAL_PARM;
  165. }
  166. /* update cmp val */
  167. FTIMER_CMPL_WRITE(instance_p, new_cmp_l);
  168. return FTIMER_TACHO_SUCCESS;
  169. }
  170. /**
  171. * @name: FTimerSetPeriod64
  172. * @msg: 设置64位计数模式下,计数器的compare的值,达到此值,如果开启中断,则开启中断
  173. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  174. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  175. * @param {u64}ticks
  176. */
  177. FError FTimerSetPeriod64(FTimerTachoCtrl *instance_p, u64 ticks)
  178. {
  179. u32 low_cmp;
  180. u32 up_cmp;
  181. FASSERT(instance_p);
  182. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  183. if (FTIMER_32_BITS == instance_p->config.timer_bits)
  184. {
  185. return FTIMER_TACHO_ERR_INVAL_PARM;
  186. }
  187. low_cmp = (u32)(GENMASK_ULL(31, 0) & ticks);
  188. up_cmp = (u32)((GENMASK_ULL(63, 32) & ticks) >> 32);
  189. /* MUST write low 32 bit first !!! */
  190. FTIMER_CMPL_WRITE(instance_p, low_cmp);
  191. FTIMER_CMPU_WRITE(instance_p, up_cmp);
  192. return FTIMER_TACHO_SUCCESS;
  193. }
  194. /**
  195. * @name: FTimerSetStartVal
  196. * @msg: 设置计数器初始值
  197. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  198. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  199. * @param {u32} cnt
  200. */
  201. inline FError FTimerSetStartVal(FTimerTachoCtrl *instance_p, u32 cnt)
  202. {
  203. u32 ret = FTIMER_TACHO_SUCCESS;
  204. FASSERT(instance_p);
  205. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  206. ret = TimerSwithBits(instance_p);
  207. if (FTIMER_TACHO_SUCCESS != ret)
  208. {
  209. return ret;
  210. }
  211. FTIMER_STAR_WRITE(instance_p, cnt);
  212. /* set force_load=1,invalid previous cmp val,
  213. otherwise the previous cmp val still work */
  214. TimerForceLoad(instance_p);
  215. FTIMER_INFO("set start val 0x%x", FTIMER_STAR_READ(instance_p));
  216. return ret;
  217. }
  218. /**
  219. * @name: FTimerGetCurCnt32
  220. * @msg: 32位模式下,获取计数器当前计数值
  221. * @return {u32}返回当前计数器的值
  222. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  223. */
  224. u32 FTimerGetCurCnt32(FTimerTachoCtrl *instance_p)
  225. {
  226. FASSERT(instance_p);
  227. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  228. return FTIMER_CNTL_READ(instance_p);
  229. }
  230. /**
  231. * @name: FTimerGetCurCnt64
  232. * @msg: 64位模式下,获取计数器当前计数值
  233. * @return {u64}返回当前计数器的值
  234. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  235. */
  236. inline u64 FTimerGetCurCnt64(FTimerTachoCtrl *instance_p)
  237. {
  238. u64 cnt = 0;
  239. FASSERT(instance_p);
  240. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  241. /* must read lower 32 bits first */
  242. cnt |= (u64)FTIMER_CNTL_READ(instance_p);
  243. cnt |= (u64)(((u64)FTIMER_CNTU_READ(instance_p)) << 32);
  244. return cnt;
  245. }
  246. /**
  247. * @name: FTimerInit
  248. * @msg: 完成TimerTacho驱动实例的初始化,使之在就绪状态
  249. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  250. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  251. * @param {FTimerTachoConfig} *config_p 驱动配置数据结构
  252. */
  253. FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p)
  254. {
  255. FASSERT(instance_p && config_p);
  256. u32 reg_val = 0;
  257. u32 Ret = FTIMER_TACHO_SUCCESS;
  258. if ((FTIMER_ONCE_CMP == config_p->cmp_type) &&
  259. (FTIMER_FREE_RUN != config_p->timer_mode))
  260. {
  261. FTIMER_ERROR("time mode shall be free-run when use once timer!!");
  262. return FTIMER_TACHO_ERR_INVAL_PARM;
  263. }
  264. if (instance_p->isready == FT_COMPONENT_IS_READY)
  265. {
  266. FTIMER_INFO("device is already initialized.!!!\r\n");
  267. return FTIMER_TACHO_ERR_IS_READ;
  268. }
  269. if (FTIMER_WORK_MODE_TIMER == config_p->work_mode)
  270. {
  271. reg_val |= FTIMER_REG_TACHO_MODE_TIMER;
  272. }
  273. else
  274. {
  275. FTIMER_ERROR("not support");
  276. return FTIMER_TACHO_ERR_INVAL_PARM;
  277. }
  278. if (FTIMER_FREE_RUN == config_p->timer_mode)
  279. {
  280. reg_val &= (~FTIMER_REG_CNT_RESTART);
  281. }
  282. else if (FTIMER_RESTART == config_p->timer_mode)
  283. {
  284. reg_val |= FTIMER_REG_CNT_RESTART;
  285. }
  286. else
  287. {
  288. FTIMER_ERROR("invalid input");
  289. return FTIMER_TACHO_ERR_INVAL_PARM;
  290. }
  291. if (FTIMER_32_BITS == config_p->timer_bits)
  292. {
  293. reg_val &= (~FTIMER_REG_CNT_SERIES_64BIT);
  294. }
  295. else if (FTIMER_64_BITS == config_p->timer_bits)
  296. {
  297. reg_val |= FTIMER_REG_CNT_SERIES_64BIT;
  298. }
  299. else
  300. {
  301. FTIMER_ERROR("invalid input");
  302. return FTIMER_TACHO_ERR_INVAL_PARM;
  303. }
  304. if (FTIMER_ONCE_CMP == config_p->cmp_type)
  305. {
  306. reg_val |= FTIMER_REG_MODE_ONCE;
  307. }
  308. else if (FTIMER_CYC_CMP == config_p->cmp_type)
  309. {
  310. reg_val &= (~FTIMER_REG_MODE_ONCE);
  311. }
  312. else
  313. {
  314. FTIMER_ERROR("invalid input");
  315. return FTIMER_TACHO_ERR_INVAL_PARM;
  316. }
  317. if (TRUE == config_p->force_load)
  318. {
  319. reg_val |= FTIMER_REG_TACHO_FORCE_LOAD;
  320. }
  321. if (TRUE == config_p->clear_cnt)
  322. {
  323. reg_val |= FTIMER_REG_CNT_CLR;
  324. }
  325. /*use input config*/
  326. if (config_p != &instance_p->config)
  327. {
  328. instance_p->config = *config_p;
  329. }
  330. FTIMER_CTRL_WRITE(instance_p, reg_val);
  331. instance_p->isready = FT_COMPONENT_IS_READY;
  332. return FTIMER_TACHO_SUCCESS;
  333. }
  334. void FTimerDeInit(FTimerTachoCtrl *instance_p)
  335. {
  336. FASSERT(instance_p);
  337. /* stop timer first */
  338. FTimerStop(instance_p);
  339. /* reset reg*/
  340. FTimerSoftwareReset(instance_p);
  341. instance_p->isready = 0;
  342. memset(instance_p, 0, sizeof(*instance_p));
  343. return;
  344. }
  345. /**
  346. * @name: FTimeSettingDump
  347. * @msg: 打印寄存器信息
  348. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  349. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  350. */
  351. FError FTimeSettingDump(const FTimerTachoCtrl *instance_p)
  352. {
  353. FASSERT(instance_p);
  354. u32 CtrlReg = FTIMER_CTRL_READ(instance_p);
  355. boolean is64Bit = ((CtrlReg & FTIMER_REG_CNT_SERIES_64BIT) != 0);
  356. FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
  357. printf("ctrl: \r\n");
  358. printf("===%d-bit timer\r\n", is64Bit ? 64 : 32);
  359. printf("===timer enabled: %d\r\n", (CtrlReg & FTIMER_REG_ENABLE) ? 1 : 0);
  360. printf("===timer mode: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_MODE_TIMER) ? 1 : 0);
  361. printf("===once timer: %d\r\n", (CtrlReg & FTIMER_REG_MODE_ONCE) ? 1 : 0);
  362. printf("===restart mode: %d\r\n", (CtrlReg & FTIMER_REG_CNT_RESTART) ? 1 : 0);
  363. printf("===in reset: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_RESET) ? 1 : 0);
  364. printf("===force load: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_FORCE_LOAD) ? 1 : 0);
  365. printf("===clear cnt: %d\r\n", (CtrlReg & FTIMER_REG_CNT_CLR) ? 1 : 0);
  366. printf("start cnt: 0x%08x\r\n", FTIMER_STAR_READ(instance_p));
  367. if (is64Bit)
  368. {
  369. printf("cmp low: 0x%08x", FTIMER_CMPL_READ(instance_p));
  370. printf("high: 0x%08x\r\n", FTIMER_CMPU_READ(instance_p));
  371. printf("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p));
  372. printf("high: 0x%08x\r\n", FTIMER_CNTU_READ(instance_p));
  373. }
  374. else
  375. {
  376. printf("cmp low: 0x%08x\r\n", FTIMER_CMPL_READ(instance_p));
  377. printf("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p));
  378. }
  379. printf("intr mask: 0x%08x\r\n", FTIMER_INTR_M_READ(instance_p));
  380. printf("intr status: 0x%08x\r\n", FTIMER_INTR_S_READ(instance_p));
  381. return FTIMER_TACHO_SUCCESS;
  382. }