ftacho.c 8.3 KB

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