#include "gtest/gtest.h" #include #include #include "scope.h" #include "test_user.h" class CadenceTest : public testing::Test { protected: static void SetUpTestSuite() { } virtual void SetUp() override { iRt_Init(); iCap_BindDeviceInterrupt(0,IC_CountMaxISR); iCap_EnableDeviceInterrupt(0); iCap_BindChannelInterrupt(0,CAP_CH(2),IC_CadenceISR); iCap_EnableChannelInterrupt(0,CAP_CH(2)); cadence_voCadenceInit(); } virtual void TearDown() override { } }; /* 踏频不同频率计算测试 */ class CadenceTest1 : public CadenceTest, public testing::WithParamInterface<::std::tuple> {}; TEST_P(CadenceTest1, FreCal) { /* Coef Cal */ cadence_voCadenceCof(); cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES; int timerPrd = TIM1CLK_KHZ * 1000 / (1000 / 25); // cnt = 18000, same as STM32 int timerCnt = 0; int cadenceSignal = 0, cadCnt = 0, cadenceSignalLast = 0; int cadencePrd = get<0>(GetParam()); int capValue = 0; int capOverflowCnt = 0, capOverflowCnt2 = 0; testGpioBValue[GPIOB] = get<1>(GetParam()); /* Cadence Cal */ for(int i = 0; i < 100000000; i++) { /* Input Cadence Signal */ cadCnt++; if(cadCnt <= (cadencePrd/2)) // 50% duty { cadenceSignal = 0; } else { cadenceSignal = 1; if(cadCnt >= cadencePrd) { cadCnt = 0; } } /* Timer */ timerCnt ++ ; if(timerCnt >= timerPrd - 1) { timerCnt = 0; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1; } /* Capture: rising and falling edge trigger*/ if(cadenceSignal - cadenceSignalLast != 0) { testCh2CapValue[TIMER1] = timerCnt; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 1; } cadenceSignalLast = cadenceSignal; /* Interrupt: update and capture */ if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP]) { capOverflowCnt ++; cadence_voCadenceCal(1); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0; } else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2]) { capOverflowCnt2 = capOverflowCnt; capOverflowCnt = 0; cadence_voCadenceCal(2); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 0; } //UdpScope::Send(0, cadence_stFreGetOut.uwFrequencyPu); } double cadFreqPu = (double)TIM1CLK_KHZ * 1000 * 2 * 1048576 / cadencePrd / FBASE / cadence_stFreGetCof.uwNumbersPulses; // Q20 if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || capOverflowCnt2 > cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1) { EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } else { EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, cadFreqPu, 2); } } INSTANTIATE_TEST_SUITE_P(DiffCadencePeriod, CadenceTest1, ::testing::Combine(::testing::Values(0, 500, 3000, 18002, 100000,1000000), ::testing::Values(0,0x0004))); /* 踏频更新中断与捕获中断同时到达测试 */ class CadenceTest2 : public CadenceTest, public testing::WithParamInterface {}; TEST_P(CadenceTest2, IntSimultFreCal) { /* Coef Cal */ cadence_voCadenceCof(); cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES; switch_flg.SysCoef_Flag = TRUE; bikespeed_voBikeSpeedCof(); ///< timer更新中断函数中有bikespeed函数,防止运行时除0 /* Test conditions */ cadence_stFreGetOut.cadence_fsm = CADENCE_HFreWork; cadence_stFreGetOut.uwCaputureNumCnt = 1; cadence_stFreGetOut.uwCaputure1Cnt = 100; cadence_stFreGetOut.uwCaputureOverflowCnt = 1; ///< OverflowCnt cant be 0 testGpioBValue[GPIOB] = 0; double overflowCnt = cadence_stFreGetOut.uwCaputureOverflowCnt; double cap1Cnt = cadence_stFreGetOut.uwCaputure1Cnt; testCh2CapValue[TIMER1] = GetParam(); /* Interrupt flag */ testTimerIntFlag2[TIMER1] = 0x0009; /* Interrupt: update and capture */ if(testTimerIntFlag2[TIMER1] != 0) { iRtCap_Isr(0); } if(testCh2CapValue[TIMER1] < (iCap_GetPeriod(0) >> 1)) { overflowCnt++; } double capValErrLast = 0, capValErr = 0, cadFreqPu = 0; capValErrLast = capValErr; capValErr = overflowCnt * 18000 + cadence_stFreGetOut.uwCaputure2Cnt - cap1Cnt; cadFreqPu = (double)TIM1CLK_KHZ * 1000 * 1048576 / ((capValErr + capValErrLast) / 2)/ FBASE / cadence_stFreGetCof.uwNumbersPulses; // Q20 if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1) { EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, 0, 0.1); } else { EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, cadFreqPu, 2); if(testCh2CapValue[TIMER1] < (iCap_GetPeriod(0) >> 1)) { EXPECT_EQ(cadence_stFreGetOut.uwCaputureOverflowCnt, 0); } else { EXPECT_EQ(cadence_stFreGetOut.uwCaputureOverflowCnt, 1); } } } INSTANTIATE_TEST_SUITE_P(DiffCadencePeriod, CadenceTest2, ::testing::Values(200, 17900)); /* 踏频模块状态机切换测试 */ class CadenceTest3 : public CadenceTest, public testing::WithParamInterface {}; TEST_P(CadenceTest3, FsmSwitch) { /* Coef Cal */ cadence_voCadenceCof(); cadence_stFreGetCof.uwNumbersPulses = CADENCE_NUMBERS_PULSES; int timerPrd = TIM1CLK_KHZ * 1000 / (1000 / 25); ///< period=25ms, cnt=18000, same as actual timer int timerCnt = 0; int cadenceSignal = 0, cadCnt = 0, cadenceSignalLast = 0; int cadencePrd = 5000; int capValue = 0; int capOverflowCnt = 0, capOverflowCnt2 = 0; testGpioBValue[GPIOB] = GetParam(); for(int i = 0; i < cadencePrd; i++) { /* Input Cadence Signal: only one rising edge */ cadCnt++; if(cadCnt <= (cadencePrd/2)) ///< 50% duty cycle squre wave, same as actual sensor { cadenceSignal = 0; } else { cadenceSignal = 1; if(cadCnt >= cadencePrd) { cadCnt = 0; } } /* Timer */ timerCnt ++ ; if(timerCnt >= timerPrd - 1) { timerCnt = 0; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1; } /* Capture: rising and falling edge trigger*/ if(cadenceSignal - cadenceSignalLast != 0) { testCh2CapValue[TIMER1] = timerCnt; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 1; } cadenceSignalLast = cadenceSignal; /* Interrupt: update and capture */ if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP]) { capOverflowCnt ++; cadence_voCadenceCal(1); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0; } else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2]) { capOverflowCnt2 = capOverflowCnt; capOverflowCnt = 0; cadence_voCadenceCal(2); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 0; } else { // do nothing } } if (iGpio_Read(HW_GPIO_CADDIR_PIN) != 0) { /* 一个正向脉冲到来,后踏频反向则切换至反向状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_BACKWOR); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } else { /* 一个正向脉冲到来,且踏频未反向切换至正常工作状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_HFreWork); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } for(int i = cadencePrd; i < 500000; i++) { if(i > 200000) { /* 踏频方向改为正 */ testGpioBValue[GPIOB] = 0; } /* Timer */ timerCnt ++ ; if(timerCnt >= timerPrd - 1) { timerCnt = 0; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1; } /* Interrupt: update */ if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP]) { capOverflowCnt ++; cadence_voCadenceCal(1); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0; } } if (iGpio_Read(HW_GPIO_CADDIR_PIN) != 0) { /* 一直反踏则维持反向状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_BACKWOR); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } else { /* 后续一段时间没有正向脉冲,且未反踏则进入空闲状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_IDLE); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } cadencePrd = 500; for(int i = 0; i < (cadencePrd * 5); i++) { /* Input Cadence Signal: only one rising edge */ cadCnt++; if(cadCnt <= (cadencePrd/2)) ///< 50% duty cycle squre wave, same as actual sensor { cadenceSignal = 0; } else { cadenceSignal = 1; if(cadCnt >= cadencePrd) { cadCnt = 0; } } /* Timer */ timerCnt ++ ; if(timerCnt >= timerPrd - 1) { timerCnt = 0; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1; } /* Capture: rising and falling edge trigger*/ if(cadenceSignal - cadenceSignalLast != 0) { testCh2CapValue[TIMER1] = timerCnt; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 1; } cadenceSignalLast = cadenceSignal; /* Interrupt: update and capture */ if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP]) { capOverflowCnt ++; cadence_voCadenceCal(1); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0; } else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2]) { capOverflowCnt2 = capOverflowCnt; capOverflowCnt = 0; cadence_voCadenceCal(2); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH2] = 0; } else { // do nothing } } if (iGpio_Read(HW_GPIO_CADDIR_PIN) != 0) { /* 一个正向脉冲到来,后踏频反向则切换至反向状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_BACKWOR); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } else { /* 踏频过高,则进入error状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_ERROR); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } for(int i = cadencePrd; i < 5000000; i++) { /* Timer */ timerCnt ++ ; if(timerCnt >= timerPrd - 1) { timerCnt = 0; testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1; } /* Interrupt: update */ if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP]) { capOverflowCnt ++; cadence_voCadenceCal(1); testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0; } } /* error状态5s后,则重新进入idle状态 */ EXPECT_EQ(cadence_stFreGetOut.cadence_fsm, CADENCE_IDLE); EXPECT_EQ(cadence_stFreGetOut.uwFrequencyPu, 0); } INSTANTIATE_TEST_SUITE_P(DiffCadenceDir, CadenceTest3,::testing::Values(0,0x0004));