test_cadence.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #include "gtest/gtest.h"
  2. #include <gtest/gtest.h>
  3. #include <tuple>
  4. #include "scope.h"
  5. #include "test_user.h"
  6. class CadenceTest : public testing::Test
  7. {
  8. protected:
  9. static void SetUpTestSuite()
  10. {
  11. }
  12. virtual void SetUp() override
  13. {
  14. iRt_Init();
  15. iCap_BindDeviceInterrupt(0,IC_CountMaxISR);
  16. iCap_EnableDeviceInterrupt(0);
  17. iCap_BindChannelInterrupt(0,CAP_CH(2),IC_CadenceISR);
  18. iCap_EnableChannelInterrupt(0,CAP_CH(2));
  19. cadence_voCadenceInit();
  20. }
  21. virtual void TearDown() override
  22. {
  23. }
  24. };
  25. /* 踏频不同频率计算测试 */
  26. class CadenceTest1 : public CadenceTest, public testing::WithParamInterface<::std::tuple<int,int>>
  27. {};
  28. TEST_P(CadenceTest1, FreCal)
  29. {
  30. /* Coef Cal */
  31. cadence_voCadenceCof();
  32. cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES;
  33. int timerPrd = TIM1CLK_KHZ * 1000 / (1000 / 25); // cnt = 18000, same as STM32
  34. int timerCnt = 0;
  35. int cadenceSignal = 0, cadCnt = 0, cadenceSignalLast = 0;
  36. int cadencePrd = get<0>(GetParam());
  37. int capValue = 0;
  38. int capOverflowCnt = 0, capOverflowCnt2 = 0;
  39. testGpioBValue[GPIOB] = get<1>(GetParam());
  40. /* Cadence Cal */
  41. for(int i = 0; i < 100000000; i++)
  42. {
  43. /* Input Cadence Signal */
  44. cadCnt++;
  45. if(cadCnt <= (cadencePrd/2)) // 50% duty
  46. {
  47. cadenceSignal = 0;
  48. }
  49. else
  50. {
  51. cadenceSignal = 1;
  52. if(cadCnt >= cadencePrd)
  53. {
  54. cadCnt = 0;
  55. }
  56. }
  57. /* Timer */
  58. timerCnt ++ ;
  59. if(timerCnt >= timerPrd - 1)
  60. {
  61. timerCnt = 0;
  62. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
  63. }
  64. /* Capture: rising and falling edge trigger*/
  65. if(cadenceSignal - cadenceSignalLast != 0)
  66. {
  67. testCh2CapValue[TIMER1] = timerCnt;
  68. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 1;
  69. }
  70. cadenceSignalLast = cadenceSignal;
  71. /* Interrupt: update and capture */
  72. if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])
  73. {
  74. capOverflowCnt ++;
  75. cadence_voCadenceCal(1);
  76. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
  77. }
  78. else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2])
  79. {
  80. capOverflowCnt2 = capOverflowCnt;
  81. capOverflowCnt = 0;
  82. cadence_voCadenceCal(2);
  83. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 0;
  84. }
  85. //UdpScope::Send(0, cadence_stFreGetOut.uwFrequencyPu);
  86. }
  87. double cadFreqPu = (double)TIM1CLK_KHZ * 1000 * 2 * 1048576 / cadencePrd / FBASE / cadence_stFreGetCof.uwNumbersPulses; // Q20
  88. if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || capOverflowCnt2 > cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1)
  89. {
  90. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  91. }
  92. else
  93. {
  94. EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, cadFreqPu, 2);
  95. }
  96. }
  97. INSTANTIATE_TEST_SUITE_P(DiffCadencePeriod, CadenceTest1,
  98. ::testing::Combine(::testing::Values(0, 500, 3000, 18002, 100000,1000000), ::testing::Values(0,0x0004)));
  99. /* 踏频更新中断与捕获中断同时到达测试 */
  100. class CadenceTest2 : public CadenceTest, public testing::WithParamInterface<int>
  101. {};
  102. TEST_P(CadenceTest2, IntSimultFreCal)
  103. {
  104. /* Coef Cal */
  105. cadence_voCadenceCof();
  106. cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES;
  107. switch_flg.SysCoef_Flag = TRUE;
  108. bikespeed_voBikeSpeedCof(); ///< timer更新中断函数中有bikespeed函数,防止运行时除0
  109. /* Test conditions */
  110. cadence_stFreGetOut.cadence_fsm = CADENCE_HFreWork;
  111. cadence_stFreGetOut.uwCaputureNumCnt = 1;
  112. cadence_stFreGetOut.uwCaputure1Cnt = 100;
  113. cadence_stFreGetOut.uwCaputureOverflowCnt = 1; ///< OverflowCnt cant be 0
  114. testGpioBValue[GPIOB] = 0;
  115. double overflowCnt = cadence_stFreGetOut.uwCaputureOverflowCnt;
  116. double cap1Cnt = cadence_stFreGetOut.uwCaputure1Cnt;
  117. testCh2CapValue[TIMER1] = GetParam();
  118. /* Interrupt flag */
  119. testTimerIntFlag2[TIMER1] = 0x0009;
  120. /* Interrupt: update and capture */
  121. if(testTimerIntFlag2[TIMER1] != 0)
  122. {
  123. iRtCap_Isr(0);
  124. }
  125. if(testCh2CapValue[TIMER1] < (iCap_GetPeriod(0) >> 1))
  126. {
  127. overflowCnt++;
  128. }
  129. double capValErrLast = 0, capValErr = 0, cadFreqPu = 0;
  130. capValErrLast = capValErr;
  131. capValErr = overflowCnt * 18000 + cadence_stFreGetOut.uwCaputure2Cnt - cap1Cnt;
  132. cadFreqPu = (double)TIM1CLK_KHZ * 1000 * 1048576 / ((capValErr + capValErrLast) / 2)/ FBASE / cadence_stFreGetCof.uwNumbersPulses; // Q20
  133. if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1)
  134. {
  135. EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, 0, 0.1);
  136. }
  137. else
  138. {
  139. EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, cadFreqPu, 2);
  140. if(testCh2CapValue[TIMER1] < (iCap_GetPeriod(0) >> 1))
  141. {
  142. EXPECT_EQ(cadence_stFreGetOut.uwCaputureOverflowCnt, 0);
  143. }
  144. else
  145. {
  146. EXPECT_EQ(cadence_stFreGetOut.uwCaputureOverflowCnt, 1);
  147. }
  148. }
  149. }
  150. INSTANTIATE_TEST_SUITE_P(DiffCadencePeriod, CadenceTest2,
  151. ::testing::Values(200, 17900));
  152. /* 踏频模块状态机切换测试 */
  153. class CadenceTest3 : public CadenceTest, public testing::WithParamInterface<int>
  154. {};
  155. TEST_P(CadenceTest3, FsmSwitch)
  156. {
  157. /* Coef Cal */
  158. cadence_voCadenceCof();
  159. cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES;
  160. int timerPrd = TIM1CLK_KHZ * 1000 / (1000 / 25); ///< period=25ms, cnt=18000, same as actual timer
  161. int timerCnt = 0;
  162. int cadenceSignal = 0, cadCnt = 0, cadenceSignalLast = 0;
  163. int cadencePrd = 5000;
  164. int capValue = 0;
  165. int capOverflowCnt = 0, capOverflowCnt2 = 0;
  166. testGpioBValue[GPIOB] = GetParam();
  167. for(int i = 0; i < cadencePrd; i++)
  168. {
  169. /* Input Cadence Signal: only one rising edge */
  170. cadCnt++;
  171. if(cadCnt <= (cadencePrd/2)) ///< 50% duty cycle squre wave, same as actual sensor
  172. {
  173. cadenceSignal = 0;
  174. }
  175. else
  176. {
  177. cadenceSignal = 1;
  178. if(cadCnt >= cadencePrd)
  179. {
  180. cadCnt = 0;
  181. }
  182. }
  183. /* Timer */
  184. timerCnt ++ ;
  185. if(timerCnt >= timerPrd - 1)
  186. {
  187. timerCnt = 0;
  188. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
  189. }
  190. /* Capture: rising and falling edge trigger*/
  191. if(cadenceSignal - cadenceSignalLast != 0)
  192. {
  193. testCh2CapValue[TIMER1] = timerCnt;
  194. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 1;
  195. }
  196. cadenceSignalLast = cadenceSignal;
  197. /* Interrupt: update and capture */
  198. if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])
  199. {
  200. capOverflowCnt ++;
  201. cadence_voCadenceCal(1);
  202. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
  203. }
  204. else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2])
  205. {
  206. capOverflowCnt2 = capOverflowCnt;
  207. capOverflowCnt = 0;
  208. cadence_voCadenceCal(2);
  209. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 0;
  210. }
  211. else
  212. {
  213. // do nothing
  214. }
  215. }
  216. if (iGpio_Read(HW_GPIO_CADDIR_PIN) != 0)
  217. {
  218. /* 一个正向脉冲到来,后踏频反向则切换至反向状态 */
  219. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_BACKWOR);
  220. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  221. }
  222. else
  223. {
  224. /* 一个正向脉冲到来,且踏频未反向切换至正常工作状态 */
  225. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_HFreWork);
  226. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  227. }
  228. for(int i = cadencePrd; i < 500000; i++)
  229. {
  230. if(i > 200000)
  231. {
  232. /* 踏频方向改为正 */
  233. testGpioBValue[GPIOB] = 0;
  234. }
  235. /* Timer */
  236. timerCnt ++ ;
  237. if(timerCnt >= timerPrd - 1)
  238. {
  239. timerCnt = 0;
  240. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
  241. }
  242. /* Interrupt: update */
  243. if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])
  244. {
  245. capOverflowCnt ++;
  246. cadence_voCadenceCal(1);
  247. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
  248. }
  249. }
  250. if (iGpio_Read(HW_GPIO_CADDIR_PIN) != 0)
  251. {
  252. /* 一直反踏则维持反向状态 */
  253. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_BACKWOR);
  254. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  255. }
  256. else
  257. {
  258. /* 后续一段时间没有正向脉冲,且未反踏则进入空闲状态 */
  259. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_IDLE);
  260. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  261. }
  262. cadencePrd = 500;
  263. for(int i = 0; i < (cadencePrd * 5); i++)
  264. {
  265. /* Input Cadence Signal: only one rising edge */
  266. cadCnt++;
  267. if(cadCnt <= (cadencePrd/2)) ///< 50% duty cycle squre wave, same as actual sensor
  268. {
  269. cadenceSignal = 0;
  270. }
  271. else
  272. {
  273. cadenceSignal = 1;
  274. if(cadCnt >= cadencePrd)
  275. {
  276. cadCnt = 0;
  277. }
  278. }
  279. /* Timer */
  280. timerCnt ++ ;
  281. if(timerCnt >= timerPrd - 1)
  282. {
  283. timerCnt = 0;
  284. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
  285. }
  286. /* Capture: rising and falling edge trigger*/
  287. if(cadenceSignal - cadenceSignalLast != 0)
  288. {
  289. testCh2CapValue[TIMER1] = timerCnt;
  290. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 1;
  291. }
  292. cadenceSignalLast = cadenceSignal;
  293. /* Interrupt: update and capture */
  294. if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])
  295. {
  296. capOverflowCnt ++;
  297. cadence_voCadenceCal(1);
  298. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
  299. }
  300. else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2])
  301. {
  302. capOverflowCnt2 = capOverflowCnt;
  303. capOverflowCnt = 0;
  304. cadence_voCadenceCal(2);
  305. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 0;
  306. }
  307. else
  308. {
  309. // do nothing
  310. }
  311. }
  312. if (iGpio_Read(HW_GPIO_CADDIR_PIN) != 0)
  313. {
  314. /* 一个正向脉冲到来,后踏频反向则切换至反向状态 */
  315. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_BACKWOR);
  316. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  317. }
  318. else
  319. {
  320. /* 踏频过高,则进入error状态 */
  321. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_ERROR);
  322. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  323. }
  324. for(int i = cadencePrd; i < 5000000; i++)
  325. {
  326. /* Timer */
  327. timerCnt ++ ;
  328. if(timerCnt >= timerPrd - 1)
  329. {
  330. timerCnt = 0;
  331. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
  332. }
  333. /* Interrupt: update */
  334. if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])
  335. {
  336. capOverflowCnt ++;
  337. cadence_voCadenceCal(1);
  338. testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
  339. }
  340. }
  341. /* error状态5s后,则重新进入idle状态 */
  342. EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_IDLE);
  343. EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0);
  344. }
  345. INSTANTIATE_TEST_SUITE_P(DiffCadenceDir, CadenceTest3,::testing::Values(0,0x0004));