Cadence.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /**
  2. * @file Cadence.c
  3. * @author Wang, Zhiyu(wangzy49@midea.com)
  4. * @brief Cadence of ebike
  5. * @version 0.1
  6. * @date 2021-09-29
  7. *
  8. * @copyright Copyright (c) 2021
  9. *
  10. */
  11. /************************************************************************
  12. Beginning of File, do not put anything above here except notes
  13. Compiler Directives:
  14. *************************************************************************/
  15. #include "syspar.h"
  16. #include "Cadence.h"
  17. #include "CodePara.h"
  18. #include "api.h"
  19. #include "board_config.h"
  20. /******************************
  21. *
  22. * Parameter
  23. *
  24. ******************************/
  25. CADENCE_COF cadence_stFreGetCof = CADENCE_COF_DEFAULT;
  26. CADENCE_OUT cadence_stFreGetOut = CADENCE_OUT_DEFAULT;
  27. static ULONG cad_pvt_ulCadFreqPu = 0;
  28. static ULONG cad_pvt_ulCapValErr = 0;
  29. static ULONG cad_pvt_ulCapValErrLast = 0;
  30. /***************************************************************
  31. Function: cadence_voCadenceCof;
  32. Description: cadence function coef cal
  33. Call by:
  34. Input Variables: N/A
  35. Output/Return Variables: N/A
  36. Subroutine Call: N/A;
  37. Reference: N/A
  38. ****************************************************************/
  39. void cadence_voCadenceCof(void)
  40. {
  41. // cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES;
  42. cadence_stFreGetCof.uwSartIntervalTimeCnt = CADENCE_START_INTERVALTIME / CADENCE_TIM_TIMERUNIT;
  43. cadence_stFreGetCof.uwNumbersValidPulse2Start = CADENCE_NUMBERS_VALIDPULSE2START;
  44. cadence_stFreGetCof.uwLfRecordTimeCnt = CADENCE_LF_RECORDTIME / CADENCE_TIM_TIMERUNIT;
  45. cadence_stFreGetCof.uwLfMinFrePu = ((((ULONG)CADENCE_LF_MINFRE << 10) / 100) << 10) / FBASE; // Q20
  46. cadence_stFreGetCof.uwHfMaxTimeCnt = CADENCE_HF_MAXTIME / CADENCE_TIM_TIMERUNIT;
  47. cadence_stFreGetCof.uwErrorResetCnt = CADENCE_ERROR_RESETTIME / CADENCE_TIM_TIMERUNIT;
  48. cadence_stFreGetCof.uwTimerUnit = CADENCE_TIM_TIMERUNIT;
  49. cadence_stFreGetCof.uwCadenceLPFgain = CADENCE_LPF_GAIN;
  50. cadence_stFreGetCof.uwMaxCadenceFre = ((ULONG)CADENCE_MAX_FREQUENCY << 20) / FBASE; // Q20
  51. }
  52. /***************************************************************
  53. Function: cadence_voCadenceIdle;
  54. Description:
  55. Call by:
  56. Input Variables: N/A
  57. Output/Return Variables: N/A
  58. Subroutine Call: N/A;
  59. Reference: N/A
  60. ****************************************************************/
  61. static void cadence_voCadenceIdle(UWORD source)
  62. {
  63. if (source == 1)
  64. {
  65. cadence_stFreGetOut.uwCaputureOverflowCnt++;
  66. if (cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwSartIntervalTimeCnt)
  67. {
  68. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  69. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  70. }
  71. }
  72. else
  73. {
  74. if (cadence_stFreGetOut.cadence_dir == CADENCE_DIR_BACKWARD)
  75. {
  76. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  77. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  78. cadence_stFreGetOut.cadence_fsm = CADENCE_BACKWOR;
  79. }
  80. if (cadence_stFreGetOut.cadence_dir == CADENCE_DIR_FORWARD)
  81. {
  82. cadence_stFreGetOut.uwCaputureNumCnt++;
  83. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  84. }
  85. if (cadence_stFreGetOut.uwCaputureNumCnt >= cadence_stFreGetCof.uwNumbersValidPulse2Start)
  86. {
  87. cadence_stFreGetOut.blCadenceCalStartState = TRUE;
  88. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  89. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  90. cadence_stFreGetOut.cadence_fsm = CADENCE_HFreWork;
  91. cadence_stFreGetOut.uwForwardCnt = 0;
  92. }
  93. }
  94. }
  95. /***************************************************************
  96. Function: cadence_voCadenceHighFrequencyWork
  97. Description:
  98. Call by: functions in main loop
  99. Input Variables: N/A
  100. Output/Return Variables: N/A
  101. Subroutine Call: N/A
  102. Reference: N/A
  103. ****************************************************************/
  104. static void cadence_voCadenceHighFrequencyWork(UWORD source)
  105. {
  106. /* 只有踏频一个脉冲会一直在此函数中,对运行无影响,即source==1 && cadence_stFreGetOut.uwCaputureNumCnt==0 的情况未处理 */
  107. if (source == 1 && cadence_stFreGetOut.uwCaputureNumCnt == 1)
  108. {
  109. cadence_stFreGetOut.uwCaputureOverflowCnt++;
  110. }
  111. else if (source == 2)
  112. {
  113. if (cadence_stFreGetOut.uwCaputureNumCnt == 0)
  114. {
  115. cadence_stFreGetOut.uwCaputureNumCnt = 1;
  116. cadence_stFreGetOut.uwCaputure1Cnt = (UWORD)iCap_GetCaptureValue(0, CAP_CH(2));
  117. }
  118. else if (cadence_stFreGetOut.uwCaputureNumCnt == 1)
  119. {
  120. cadence_stFreGetOut.uwForwardCnt++;
  121. cadence_stFreGetOut.uwCaputureNumCnt = 2;
  122. cadence_stFreGetOut.uwCaputure2Cnt = (UWORD)iCap_GetCaptureValue(0, CAP_CH(2));
  123. cad_pvt_ulCapValErrLast = cad_pvt_ulCapValErr;
  124. cad_pvt_ulCapValErr = ((ULONG)cadence_stFreGetOut.uwCaputureOverflowCnt * 720 * cadence_stFreGetCof.uwTimerUnit) -
  125. cadence_stFreGetOut.uwCaputure1Cnt + cadence_stFreGetOut.uwCaputure2Cnt;
  126. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  127. /* Cadence Freq Cal */
  128. cad_pvt_ulCadFreqPu = (ULONG)(((UQWORD)HW_TIM1CLK_KHZ * 1000 << 20) / ((((UQWORD)cad_pvt_ulCapValErr + (UQWORD)cad_pvt_ulCapValErrLast)>>1)* cadence_stFreGetCof.uwNumbersPulses * FBASE));
  129. cadence_stFreGetOut.uwCaputureNumCnt = 1;
  130. cadence_stFreGetOut.uwCaputure1Cnt = cadence_stFreGetOut.uwCaputure2Cnt;
  131. }
  132. else
  133. {
  134. //do noting
  135. }
  136. }
  137. else
  138. {
  139. //do noting
  140. }
  141. if (cadence_stFreGetOut.cadence_dir == CADENCE_DIR_BACKWARD)
  142. {
  143. cadence_stFreGetOut.cadence_fsm = CADENCE_BACKWOR;
  144. }
  145. if (cad_pvt_ulCadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre)
  146. {
  147. cadence_stFreGetOut.uwFrequencyPu = 0;
  148. cadence_stFreGetOut.uwLPFFrequencyPu = 0;
  149. cadence_stFreGetOut.blCadenceCalStartState = FALSE;
  150. cadence_stFreGetOut.blCadenceSensorErrorFlg = TRUE;
  151. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  152. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  153. cadence_stFreGetOut.uwCaputure2Cnt = 0;
  154. cadence_stFreGetOut.uwCaputure1Cnt = 0;
  155. cadence_stFreGetOut.cadence_dir = CADENCE_DIR_ERROR;
  156. cadence_stFreGetOut.cadence_fsm = CADENCE_ERROR;
  157. cadence_stFreGetOut.uwFreqPercent = 0;
  158. }
  159. else if (cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwHfMaxTimeCnt)
  160. {
  161. cadence_stFreGetOut.uwFrequencyPu = 0;
  162. cadence_stFreGetOut.uwLPFFrequencyPu = 0;
  163. cadence_stFreGetOut.blCadenceCalStartState = FALSE;
  164. cadence_stFreGetOut.blCadenceSensorErrorFlg = FALSE;
  165. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  166. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  167. cadence_stFreGetOut.uwCaputure2Cnt = 0;
  168. cadence_stFreGetOut.uwCaputure1Cnt = 0;
  169. cadence_stFreGetOut.cadence_dir = CADENCE_DIR_IDLE;
  170. cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
  171. cadence_stFreGetOut.uwFreqPercent = 0;
  172. }
  173. else
  174. {
  175. cadence_stFreGetOut.uwFrequencyPu = cad_pvt_ulCadFreqPu; // Q20
  176. cadence_stFreGetOut.uwLPFFrequencyPu = (cadence_stFreGetOut.uwLPFFrequencyPu * cadence_stFreGetCof.uwCadenceLPFgain +
  177. cadence_stFreGetOut.uwFrequencyPu * (100 - cadence_stFreGetCof.uwCadenceLPFgain)) / 100; // Q20
  178. cadence_stFreGetOut.uwFreqPercent = (UWORD)(((ULONG)cadence_stFreGetOut.uwLPFFrequencyPu << 14) / cadence_stFreGetCof.uwMaxCadenceFre); // Q14
  179. }
  180. }
  181. /***************************************************************
  182. Function: cadence_voCadenceBackword
  183. Description:
  184. Call by: functions in main loop
  185. Input Variables: N/A
  186. Output/Return Variables: N/A
  187. Subroutine Call: N/A
  188. Reference: N/A
  189. ****************************************************************/
  190. static void cadence_voCadenceBackword(UWORD source)
  191. {
  192. cadence_stFreGetOut.uwFrequencyPu = 0;
  193. cadence_stFreGetOut.uwLPFFrequencyPu = 0;
  194. cadence_stFreGetOut.uwFreqPercent = 0;
  195. if (cadence_stFreGetOut.cadence_dir == CADENCE_DIR_FORWARD)
  196. {
  197. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  198. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  199. cadence_stFreGetOut.uwCaputure2Cnt = 0;
  200. cadence_stFreGetOut.uwCaputure1Cnt = 0;
  201. cadence_stFreGetOut.uwFreqPercent = 0;
  202. cadence_stFreGetOut.cadence_fsm = CADENCE_HFreWork;
  203. }
  204. }
  205. /***************************************************************
  206. Function: cadence_voCadenceDir
  207. Description: cadence frequency get
  208. Call by: functions in main loop
  209. Input Variables: N/A
  210. Output/Return Variables: N/A
  211. Subroutine Call: N/A
  212. Reference: N/A
  213. ****************************************************************/
  214. static void cadence_voCadenceDir(void)
  215. {
  216. if (iGpio_Read(HW_GPIO_CADDIR_PIN) == 0)
  217. {
  218. cadence_stFreGetOut.cadence_dir = CADENCE_DIR_FORWARD;
  219. }
  220. else
  221. {
  222. cadence_stFreGetOut.cadence_dir = CADENCE_DIR_BACKWARD;
  223. }
  224. }
  225. /***************************************************************
  226. Function: cadence_voCadenceError
  227. Description:
  228. Call by:
  229. Input Variables: N/A
  230. Output/Return Variables: N/A
  231. Subroutine Call: N/A
  232. Reference: N/A
  233. ****************************************************************/
  234. static void cadence_voCadenceError(UWORD source)
  235. {
  236. if (source == 1)
  237. {
  238. cadence_stFreGetOut.uwCaputureErrorCnt++;
  239. }
  240. if (cadence_stFreGetOut.uwCaputureErrorCnt == cadence_stFreGetCof.uwErrorResetCnt)
  241. {
  242. cadence_voCadenceInit();
  243. cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
  244. }
  245. }
  246. /***************************************************************
  247. Function: cadence_voFreGetInit
  248. Description: cadence frequency get initialization
  249. Call by:
  250. Input Variables: N/A
  251. Output/Return Variables: N/A
  252. Subroutine Call: N/A
  253. Reference: N/A
  254. ****************************************************************/
  255. void cadence_voCadenceInit(void)
  256. {
  257. cadence_stFreGetOut.uwFrequencyPu = 0;
  258. cadence_stFreGetOut.uwLPFFrequencyPu = 0;
  259. cadence_stFreGetOut.uwCaputure1Cnt = 0;
  260. cadence_stFreGetOut.uwCaputure2Cnt = 0;
  261. cadence_stFreGetOut.uwCaputureNumCnt = 0;
  262. cadence_stFreGetOut.uwCaputureErrorCnt = 0;
  263. cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
  264. cadence_stFreGetOut.blCadenceSensorErrorFlg = FALSE;
  265. cadence_stFreGetOut.blCadenceCalStartState = FALSE;
  266. cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
  267. cadence_stFreGetOut.cadence_dir = CADENCE_DIR_IDLE;
  268. cad_pvt_ulCadFreqPu = 0;
  269. cad_pvt_ulCapValErr = 0;
  270. cad_pvt_ulCapValErrLast = 0;
  271. }
  272. /***************************************************************
  273. Function: cadence_voCadenceCal
  274. Description: cadence frequency get
  275. Call by:
  276. Input Variables: N/A
  277. Output/Return Variables: N/A
  278. Subroutine Call: N/A
  279. Reference: N/A
  280. ****************************************************************/
  281. void cadence_voCadenceCal(UWORD source)
  282. {
  283. cadence_voCadenceDir();
  284. switch (cadence_stFreGetOut.cadence_fsm)
  285. {
  286. case CADENCE_IDLE:
  287. cadence_voCadenceIdle(source);
  288. break;
  289. case CADENCE_HFreWork:
  290. cadence_voCadenceHighFrequencyWork(source);
  291. break;
  292. case CADENCE_BACKWOR:
  293. cadence_voCadenceBackword(source);
  294. break;
  295. case CADENCE_ERROR:
  296. cadence_voCadenceError(source);
  297. break;
  298. default:
  299. break;
  300. }
  301. }
  302. /*************************************************************************
  303. End of this File (EOF)!
  304. Do not put anything after this part!
  305. *************************************************************************/