ftacho.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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: ftacho.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-05-20 09:08:52
  17. * Description:  This file is for user tacho API implmentation
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. * 1.0 liushengming 2022/05/20 first commit
  23. */
  24. /***************************** Include Files *********************************/
  25. #include <string.h>
  26. #include "fassert.h"
  27. #include "fkernel.h"
  28. #include "fsleep.h"
  29. #include "ftimer_tacho_hw.h"
  30. #include "ftimer_tacho.h"
  31. #include "fparameters.h"
  32. /************************** Function Prototypes ******************************/
  33. /**
  34. * @name: FTachoInit
  35. * @msg: 初始化Tacho,并且使能计数器和tachometer
  36. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  37. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  38. * @param {FTimerTachoConfig} *config_p 驱动配置数据结构
  39. */
  40. FError FTachoInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p)
  41. {
  42. FASSERT(instance_p && config_p);
  43. u32 reg_val = 0;
  44. if (instance_p->isready == FT_COMPONENT_IS_READY)
  45. {
  46. FTIMER_INFO("Device is already initialized !!!\r\n");
  47. return FTIMER_TACHO_ERR_IS_READ;
  48. }
  49. /* set work mode */
  50. if (FTIMER_WORK_MODE_TACHO == config_p->work_mode)
  51. {
  52. reg_val |= FTIMER_REG_TACHO_MODE_TACHO;
  53. reg_val |= FTACHO_REG_CAP_IN_ENABLE;
  54. /* plus num of rpm calculate period */
  55. FTIMER_CMPL_WRITE(instance_p, config_p->plus_num);
  56. }
  57. else if (FTIMER_WORK_MODE_CAPTURE == config_p->work_mode)
  58. {
  59. reg_val |= FTIMER_REG_TACHO_MODE_CAPTURE;
  60. reg_val |= FTIMER_REG_TACHO_CAPTURE_ENABLE;
  61. /* set capture cnt to assert capture intr */
  62. reg_val |= FTIMER_REG_TACHO_CAPTURE_CNT_MASK & (config_p->captue_cnt << FTIMER_REG_TACHO_CAPTURE_CNT_SHIFT);
  63. reg_val |= FTIMER_REG_ENABLE;
  64. }
  65. else
  66. {
  67. FTACHO_ERROR("Not support work_mode.");
  68. return FTIMER_TACHO_ERR_INVAL_PARM;
  69. }
  70. /* set timer bits */
  71. if (FTIMER_32_BITS == config_p->timer_bits)
  72. {
  73. reg_val &= (~FTIMER_REG_CNT_SERIES_64BIT);
  74. }
  75. else if (FTIMER_64_BITS == config_p->timer_bits)
  76. {
  77. reg_val |= FTIMER_REG_CNT_SERIES_64BIT;
  78. }
  79. else
  80. {
  81. FTACHO_ERROR("Invalid input 32/64bits.");
  82. return FTIMER_TACHO_ERR_INVAL_PARM;
  83. }
  84. /* set edge mode */
  85. if (FTACHO_FALLING_EDGE == config_p->edge_mode)
  86. {
  87. reg_val &= ~FTACHO_REG_MODE_MASK;
  88. reg_val |= FTACHO_REG_MODE_FALLING_EDGE;
  89. }
  90. else if (FTACHO_RISING_EDGE == config_p->edge_mode)
  91. {
  92. reg_val &= ~FTACHO_REG_MODE_MASK;
  93. reg_val |= FTACHO_REG_MODE_RISING_EDGE;
  94. }
  95. else if (FTACHO_DOUBLE_EDGE == config_p->edge_mode)
  96. {
  97. reg_val &= ~FTACHO_REG_MODE_MASK;
  98. reg_val |= FTACHO_REG_MODE_DOUBLE_EDGE;
  99. }
  100. else
  101. {
  102. FTACHO_ERROR("Invalid input edge.");
  103. return FTIMER_TACHO_ERR_INVAL_PARM;
  104. }
  105. /* set jitter level */
  106. reg_val |= FTACHO_REG_ANTI_JITTER_MASK &
  107. (config_p->jitter_level << FTACHO_REG_ANTI_JITTER_SHIFT);
  108. //use input config
  109. if (config_p != &instance_p->config)
  110. {
  111. instance_p->config = *config_p;
  112. }
  113. FTIMER_CTRL_WRITE(instance_p, reg_val);
  114. instance_p->isready = FT_COMPONENT_IS_READY;
  115. return FTIMER_TACHO_SUCCESS;
  116. }
  117. /**
  118. * @name: FTachoGetFanRPM
  119. * @msg: 获取风扇的转速值
  120. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  121. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  122. * @param {u32} *rpm 将获取到的数值写入到此地址
  123. */
  124. FError FTachoGetFanRPM(FTimerTachoCtrl *instance_p, u32 *rpm)
  125. {
  126. u32 loop_cnt;
  127. u32 raw_dat;
  128. FASSERT(instance_p);
  129. if (instance_p->isready != FT_COMPONENT_IS_READY || instance_p->config.work_mode != FTIMER_WORK_MODE_TACHO)
  130. {
  131. FTIMER_ERROR("Device is not ready or not work on TACHO_MODE!!!");
  132. return FTIMER_TACHO_ERR_NOT_READY;
  133. }
  134. u32 cnt_num = FTIMER_CMPL_READ(instance_p);
  135. for (loop_cnt = 0;; loop_cnt++)
  136. {
  137. raw_dat = FTACHO_RESU_READ(instance_p);
  138. /* wait for tacho result */
  139. if (raw_dat & FTACHO_REG_RESU_ISVALID)
  140. {
  141. break;
  142. }
  143. if (loop_cnt < 300)
  144. {
  145. fsleep_millisec(20); //20ms
  146. }
  147. else
  148. {
  149. return FTIMER_TACHO_ERR_ABORT;
  150. }
  151. }
  152. raw_dat &= FTACHO_REG_RESU_MASK;
  153. if (0 == raw_dat)
  154. {
  155. *rpm = 0;
  156. }
  157. else
  158. {
  159. /* calculate rpm */
  160. /* (60(second) * freq * tacho) / (2 * (cmp_l + 1)) cmp_l */
  161. *rpm = (FTIMER_CLK_FREQ_HZ * 60 * raw_dat) / (2 * (cnt_num + 1));
  162. }
  163. return FTIMER_TACHO_SUCCESS;
  164. }
  165. /**
  166. * @name: FTachoGetCaptureCnt
  167. * @msg: 获取capture模式下,tacho输入脉冲的个数
  168. * @return {u32}返回获取到的数值
  169. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  170. */
  171. u32 FTachoGetCaptureCnt(FTimerTachoCtrl *instance_p)
  172. {
  173. u32 cap_cnt = FTIMER_TACHO_SUCCESS;
  174. FASSERT(instance_p);
  175. if (instance_p->isready != FT_COMPONENT_IS_READY || instance_p->config.work_mode != FTIMER_WORK_MODE_CAPTURE)
  176. {
  177. FTIMER_ERROR("Device is not ready or not work on CAPTURE_MODE!!!");
  178. return FTIMER_TACHO_ERR_NOT_READY;
  179. }
  180. /* read cap cnt */
  181. cap_cnt = FTIMER_CNTL_READ(instance_p);
  182. return cap_cnt;
  183. }
  184. /**
  185. * @name: FTimerSwithMode
  186. * @msg: 切换定时器模式和tachometer-capture模式
  187. * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
  188. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  189. * @param {FTimerTachoConfig} *pNewConfig 新的驱动配置数据结构
  190. */
  191. FError FTimerSwithMode(FTimerTachoCtrl *instance_p, FTimerTachoConfig *pNewConfig)
  192. {
  193. FASSERT(instance_p && pNewConfig);
  194. u32 ret = FTIMER_TACHO_SUCCESS;
  195. if (instance_p->config.work_mode == pNewConfig->work_mode)
  196. {
  197. return FTIMER_TACHO_SUCCESS;
  198. }
  199. /* disable and clear timer */
  200. u32 reg_val = FTIMER_CTRL_READ(instance_p);
  201. reg_val &= (~FTIMER_REG_ENABLE);
  202. reg_val |= FTIMER_REG_CNT_CLR;
  203. FTIMER_CTRL_WRITE(instance_p, reg_val);
  204. if (FTIMER_WORK_MODE_TIMER == pNewConfig->work_mode)
  205. {
  206. ret = FTimerInit(instance_p, pNewConfig);
  207. }
  208. else
  209. {
  210. ret = FTachoInit(instance_p, pNewConfig);
  211. }
  212. return ret;
  213. }
  214. /**
  215. * @name: FTachoSetCntPeriod
  216. * @msg: 配置 tach计数周期 = pulse_num
  217. * @return {void}
  218. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  219. * @param {u32}计数ticks
  220. */
  221. void FTachoSetCntPeriod(FTimerTachoCtrl *instance_p, u32 ticks)
  222. {
  223. FTIMER_CMPL_WRITE(instance_p, ticks);
  224. }
  225. /**
  226. * @name: FTachoSetOverLimit
  227. * @msg: 预设tacho的最大值
  228. * @return {void}
  229. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  230. * @param {u32}上限值
  231. */
  232. void FTachoSetOverLimit(FTimerTachoCtrl *instance_p, u32 overLim)
  233. {
  234. FTACHO_OVER_WRITE(instance_p, overLim);
  235. }
  236. /**
  237. * @name: FTachoSetUnderLimit
  238. * @msg: 预设tacho的最小值
  239. * @return {void}
  240. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  241. * @param {u32}下限值
  242. */
  243. void FTachoSetUnderLimit(FTimerTachoCtrl *instance_p, u32 underLim)
  244. {
  245. FTACHO_UNDER_WRITE(instance_p, underLim);
  246. }
  247. /**
  248. * @name: FTachoDeInit
  249. * @msg: 去初始化,寄存器复位,结构体参数置0
  250. * @return {void}
  251. * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
  252. */
  253. void FTachoDeInit(FTimerTachoCtrl *instance_p)
  254. {
  255. FASSERT(instance_p);
  256. /* reset reg*/
  257. FTimerSoftwareReset(instance_p);
  258. instance_p->isready = 0;
  259. memset(instance_p, 0, sizeof(*instance_p));
  260. return;
  261. }