test_cursample_calib.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "gtest/gtest.h"
  2. #include <gtest/gtest.h>
  3. #include <stdint.h>
  4. #include <tuple>
  5. #include "scope.h"
  6. #include "test_user.h"
  7. #include <cmath>
  8. class CurSampleCalibTest : public testing::Test
  9. {
  10. protected:
  11. static void SetUpTestSuite()
  12. {
  13. CodeParaInit();
  14. adc_voSampleInit();
  15. pwm_voInit();
  16. scm_uwSpdFbkLpfAbsPu = 0;
  17. }
  18. virtual void SetUp() override
  19. {}
  20. virtual void TearDown() override
  21. {
  22. adc_voSampleInit();
  23. pwm_voInit();
  24. scm_uwSpdFbkLpfAbsPu = 0;
  25. }
  26. };
  27. class CurSampleCalibTest1 : public CurSampleCalibTest, public testing::WithParamInterface<::std::tuple<double, double, double>>
  28. {};
  29. TEST_P(CurSampleCalibTest1, SingResCalib)
  30. {
  31. int timerPrd = HW_PWM_PERIOD;
  32. int timerCnt = 0, timerCntDir = 0, prdCnt = 0;
  33. double phase, ia, ib, ic, iaRdson, ibRdson, icRdson;
  34. double currentFreqHz = 100; // unit: Hz
  35. double currentMod = get<0>(GetParam()); // unit: A
  36. double rdsonCoef = get<1>(GetParam());
  37. double emf = get<2>(GetParam()); // unit: V
  38. double loopNum = 100000000;
  39. double spdAbsTarget = emf * 32768 * 1000 / M_FLUX_WB / 2 / 3.14 * 1000 / FBASE; // Q15
  40. /* Coef Cal */
  41. adc_voSampleCoef(&adc_stCof);
  42. adc_stCof.uwIaOffset = 2048;
  43. adc_stCof.uwIbOffset = 2048;
  44. adc_stCof.uwIcOffset = 2048;
  45. adc_stCof.uwIdcOffset = 0;
  46. pwm_stGenCoefIn.uwPWMDutyMax = cp_stControlPara.swPWMMaxDuty;
  47. pwm_stGenCoefIn.uwPWM7To5Duty = cp_stControlPara.swPWM7to5Duty;
  48. pwm_stGenCoefIn.uwPWMMinSample1Pu = cp_stControlPara.swPWMMinSampleDuty1;
  49. pwm_stGenCoefIn.uwPWMMinSample2Pu = cp_stControlPara.swPWMMinSampleDuty2;
  50. pwm_stGenCoefIn.uwPWMMinSample3Pu = cp_stControlPara.swPWMMinSampleDuty3;
  51. pwm_stGenCoefIn.uwSampleSteadyPu = cp_stControlPara.swPWMSampleToSteady;
  52. pwm_stGenCoefIn.uwSingelResisSamplePu = cp_stControlPara.swPWMSampleSigR;
  53. pwm_stGenCoefIn.uwOvmNo = cp_stControlPara.swPWMOverMdlMode;
  54. pwm_stGenCoefIn.uwPWMPd = HW_PWM_PERIOD;
  55. pwm_voGenCoef(&pwm_stGenCoefIn, &pwm_stGenCoef);
  56. for (int i = 0; i < loopNum; i++)
  57. {
  58. /* Current */
  59. phase = currentFreqHz * 2 * 3.14 * i / (TIM0CLK_KHZ * 1000);
  60. ia = currentMod * sin(phase);
  61. ib = currentMod * sin(phase + (double)2 / 3 * 3.14);
  62. ic = currentMod * sin(phase + (double)4 / 3 * 3.14);
  63. iaRdson = ia * rdsonCoef;
  64. ibRdson = ib * rdsonCoef;
  65. icRdson = ic * rdsonCoef;
  66. /* Timer: centre-aligned */
  67. if (timerCntDir == 0)
  68. {
  69. timerCnt++;
  70. if (timerCnt == (timerPrd / 2))
  71. {
  72. testTimerIntFlg[TIMER0][TIMER_INT_FLAG_UP] = 1;
  73. timerCntDir = 1;
  74. }
  75. }
  76. else
  77. {
  78. timerCnt--;
  79. if (timerCnt == 0)
  80. {
  81. testTimerIntFlg[TIMER0][TIMER_INT_FLAG_UP] = 1;
  82. timerCntDir = 0;
  83. prdCnt++;
  84. }
  85. }
  86. /* ADC Trigger */
  87. if (timerCntDir == 0)
  88. {
  89. if (prdCnt % 2 == 1)
  90. {
  91. if (timerCnt == pwm_stGenOut.uwRdsonTrig)
  92. {
  93. double iaReg = (double)adc_stCof.uwIaOffset - iaRdson * 100 * 2048 / ADC_IPHASE_CUR_MAX_AP; // Negative direction current
  94. if (iaReg < 0)
  95. {
  96. iaReg = 0;
  97. }
  98. if (iaReg > 4096)
  99. {
  100. iaReg = 4096;
  101. }
  102. double ibReg = (double)adc_stCof.uwIbOffset - ibRdson * 100 * 2048 / ADC_IPHASE_CUR_MAX_AP; // Negative direction current
  103. if (ibReg < 0)
  104. {
  105. ibReg = 0;
  106. }
  107. if (ibReg > 4096)
  108. {
  109. ibReg = 4096;
  110. }
  111. double icReg = (double)adc_stCof.uwIcOffset - icRdson * 100 * 2048 / ADC_IPHASE_CUR_MAX_AP; // Negative direction current
  112. if (icReg < 0)
  113. {
  114. icReg = 0;
  115. }
  116. if (icReg > 4096)
  117. {
  118. icReg = 4096;
  119. }
  120. ADC_IDATA0(ADC0) = iaReg;
  121. ADC_IDATA1(ADC0) = ibReg;
  122. ADC_IDATA2(ADC0) = icReg;
  123. testAdcIntFlg[ADC0][ADC_INT_FLAG_EOIC] = 1;
  124. }
  125. }
  126. else
  127. {
  128. if (timerCnt == pwm_stGenOut.uwSigRTrig)
  129. {
  130. switch (pwm_stGenOut.uwSingelRSampleArea)
  131. {
  132. case SampleA:
  133. ADC_IDATA0(ADC1) = (UWORD)(adc_stCof.uwIdcOffset + abs(ia) * 100 * 4096 / ADC_IDC_CUR_MAX_AP);
  134. if (ADC_IDATA0(ADC1) > 4096)
  135. {
  136. ADC_IDATA0(ADC1) = 4096;
  137. }
  138. break;
  139. case SampleB:
  140. ADC_IDATA0(ADC1) = (UWORD)(adc_stCof.uwIdcOffset + abs(ib) * 100 * 4096 / ADC_IDC_CUR_MAX_AP);
  141. if (ADC_IDATA0(ADC1) > 4096)
  142. {
  143. ADC_IDATA0(ADC1) = 4096;
  144. }
  145. break;
  146. case SampleC:
  147. ADC_IDATA0(ADC1) = (UWORD)(adc_stCof.uwIdcOffset + abs(ic) * 100 * 4096 / ADC_IDC_CUR_MAX_AP);
  148. if (ADC_IDATA0(ADC1) > 4096)
  149. {
  150. ADC_IDATA0(ADC1) = 4096;
  151. }
  152. break;
  153. default:
  154. break;
  155. }
  156. testAdcIntFlg[ADC1][ADC_INT_FLAG_EOIC] = 1;
  157. }
  158. }
  159. }
  160. /* ADC Interrupt */
  161. if (testAdcIntFlg[ADC0][ADC_INT_FLAG_EOIC] == 1)
  162. {
  163. adc_uwRdsonUReg = ADC_IDATA0(ADC0);
  164. adc_uwRdsonVReg = ADC_IDATA1(ADC0);
  165. adc_uwRdsonWReg = ADC_IDATA2(ADC0);
  166. testAdcIntFlg[ADC0][ADC_INT_FLAG_EOIC] = 0;
  167. }
  168. if (testAdcIntFlg[ADC1][ADC_INT_FLAG_EOIC] == 1)
  169. {
  170. adc_uwADDMAPhase1 = ADC_IDATA0(ADC1);
  171. testAdcIntFlg[ADC1][ADC_INT_FLAG_EOIC] = 0;
  172. }
  173. /* Timer Interrupt */
  174. if (testTimerIntFlg[TIMER0][TIMER_INT_FLAG_UP] == 1)
  175. {
  176. if ((timerCntDir == 1) && (prdCnt % 2 == 1))
  177. {
  178. /* Speed Mock */
  179. if(scm_uwSpdFbkLpfAbsPu < spdAbsTarget)
  180. {
  181. scm_uwSpdFbkLpfAbsPu += 20; ///< 转速需模拟实际从0上升,否则采样校准系数会计算为0
  182. }
  183. else
  184. {
  185. scm_uwSpdFbkLpfAbsPu = spdAbsTarget;
  186. }
  187. /* Sample and Calibration */
  188. adc_voSampleUp(&adc_stCof, &adc_stUpOut);
  189. adc_voSampleDown(&adc_stCof, &adc_stDownOut);
  190. adc_voSRCalibration(&adc_stCof, &adc_stUpOut, &adc_stDownOut);
  191. /* ADC Trigger Cal */
  192. double phase2 = atan2((double)currentMod * M_LQ_NOLOAD_MH / 100 / 1000000, (double )M_FLUX_WB / 1000000) ;
  193. pwm_stGenIn.swUalphaPu = (SWORD)(emf * 10 * sin(phase + phase2) * 16384 / cos(phase2) / VBASE); // Q14
  194. pwm_stGenIn.swUbetaPu = (SWORD)(emf * 10 * cos(phase + phase2) * 16384 / cos(phase2) / VBASE); // Q14
  195. pwm_stGenIn.uwVdcPu = (UWORD)(36 * 10 * 16384 / VBASE); // Q14
  196. pwm_voGen(&pwm_stGenIn, &pwm_stGenCoef, &pwm_stGenOut);
  197. /* Scope */
  198. UdpScope::Send(0, adc_stDownOut.slSampIcPu, adc_stUpOut.swCalibIcPu, adc_stDownOut.swIcPu);
  199. //UdpScope::Send(0, scm_uwSpdFbkLpfAbsPu, pwm_stGenOut.blSampleCalibFlag);
  200. /* Determine whether the unit test pass */
  201. if (prdCnt > (loopNum / HW_PWM_PERIOD - 5))
  202. {
  203. if (!adc_stCof.blCalibCalFlag)
  204. {
  205. if(adc_stDownOut.ulISamplePeakPu > 32767)
  206. {
  207. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 780 / 1024, adc_stDownOut.swIaPu, 10); ///< 系数为立即数,程序中更改后测试用例需要随之更改
  208. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 780 / 1024, adc_stDownOut.swIbPu, 10);
  209. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 780 / 1024, adc_stDownOut.swIcPu, 10);
  210. }
  211. // else if(adc_stDownOut.ulISamplePeakPu > 25800)
  212. // {
  213. // EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 1024 / 1024, adc_stDownOut.swIaPu, 10); ///< 系数为立即数,程序中更改后测试用例需要随之更改
  214. // EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 1024 / 1024, adc_stDownOut.swIbPu, 10);
  215. // EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 1024 / 1024, adc_stDownOut.swIcPu, 10);
  216. // }
  217. else
  218. {
  219. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 1024 / 1024, adc_stDownOut.swIaPu, 10); ///< 系数为立即数,程序中更改后测试用例需要随之更改
  220. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 1024 / 1024, adc_stDownOut.swIbPu, 10);
  221. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 1024 / 1024, adc_stDownOut.swIcPu, 10);
  222. }
  223. }
  224. else
  225. {
  226. if (1024 / rdsonCoef < adc_stCof.uwCalibcoefMin)
  227. {
  228. if (currentMod * rdsonCoef * 100 >= ADC_IPHASE_CUR_MAX_AP)
  229. {
  230. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 780 / 1024, adc_stDownOut.swIaPu, 50);
  231. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 780 / 1024, adc_stDownOut.swIbPu, 50);
  232. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 780 / 1024, adc_stDownOut.swIcPu, 50);
  233. }
  234. else
  235. {
  236. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * adc_stCof.uwCalibcoefMin / 1024, adc_stDownOut.swIaPu, 10);
  237. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * adc_stCof.uwCalibcoefMin / 1024, adc_stDownOut.swIbPu, 10);
  238. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * adc_stCof.uwCalibcoefMin / 1024, adc_stDownOut.swIcPu, 10);
  239. }
  240. }
  241. else if (1024 / rdsonCoef > adc_stCof.uwCalibcoefMax)
  242. {
  243. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIaPu, 50);
  244. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIbPu, 50);
  245. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIcPu, 50);
  246. }
  247. else
  248. {
  249. if (currentMod < 20)
  250. {
  251. EXPECT_NEAR(ia * 100 * 16384 / IBASE, adc_stDownOut.swIaPu, 0.5 * 100 * 16384 / IBASE);
  252. EXPECT_NEAR(ib * 100 * 16384 / IBASE, adc_stDownOut.swIbPu, 0.5 * 100 * 16384 / IBASE);
  253. EXPECT_NEAR(ic * 100 * 16384 / IBASE, adc_stDownOut.swIcPu, 0.5 * 100 * 16384 / IBASE);
  254. }
  255. else
  256. {
  257. EXPECT_NEAR(ia * 100 * 16384 / IBASE, adc_stDownOut.swIaPu, 1.5 * 100 * 16384 / IBASE);
  258. EXPECT_NEAR(ib * 100 * 16384 / IBASE, adc_stDownOut.swIbPu, 1.5 * 100 * 16384 / IBASE);
  259. EXPECT_NEAR(ic * 100 * 16384 / IBASE, adc_stDownOut.swIcPu, 1.5 * 100 * 16384 / IBASE);
  260. }
  261. }
  262. }
  263. }
  264. }
  265. testTimerIntFlg[TIMER0][TIMER_INT_FLAG_UP] = 0;
  266. }
  267. }
  268. }
  269. INSTANTIATE_TEST_SUITE_P(DiffCurMod, CurSampleCalibTest1,
  270. ::testing::Combine(::testing::Values(5, 19, 39, 55), ::testing::Values(0.4, 0.8, 2.1, 6), ::testing::Values(1, 2, 10)));