ftimer.c 13 KB

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