test_cursample_calib.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. /* Api变量赋值 */
  174. Adcs[1].Results[HW_ADC_IA_CH] = adc_uwRdsonUReg;
  175. Adcs[1].Results[HW_ADC_IB_CH] = adc_uwRdsonVReg;
  176. Adcs[1].Results[HW_ADC_IC_CH] = adc_uwRdsonWReg;
  177. Adcs[2].Results[HW_ADC_IDC_CH] = adc_uwADDMAPhase1;
  178. /* Timer Interrupt */
  179. if (testTimerIntFlg[TIMER0][TIMER_INT_FLAG_UP] == 1)
  180. {
  181. if ((timerCntDir == 1) && (prdCnt % 2 == 1))
  182. {
  183. /* Speed Mock */
  184. if(scm_uwSpdFbkLpfAbsPu < spdAbsTarget)
  185. {
  186. scm_uwSpdFbkLpfAbsPu += 20; ///< 转速需模拟实际从0上升,否则采样校准系数会计算为0
  187. }
  188. else
  189. {
  190. scm_uwSpdFbkLpfAbsPu = spdAbsTarget;
  191. }
  192. /* Sample and Calibration */
  193. adc_voSampleUp(&adc_stCof, &adc_stUpOut);
  194. adc_voSampleDown(&adc_stCof, &adc_stDownOut);
  195. adc_voSRCalibration(&adc_stCof, &adc_stUpOut, &adc_stDownOut);
  196. /* ADC Trigger Cal */
  197. double phase2 = atan2((double)currentMod * M_LQ_NOLOAD_MH / 100 / 1000000, (double )M_FLUX_WB / 1000000) ;
  198. pwm_stGenIn.swUalphaPu = (SWORD)(emf * 10 * sin(phase + phase2) * 16384 / cos(phase2) / VBASE); // Q14
  199. pwm_stGenIn.swUbetaPu = (SWORD)(emf * 10 * cos(phase + phase2) * 16384 / cos(phase2) / VBASE); // Q14
  200. pwm_stGenIn.uwVdcPu = (UWORD)(36 * 10 * 16384 / VBASE); // Q14
  201. pwm_voGen(&pwm_stGenIn, &pwm_stGenCoef, &pwm_stGenOut);
  202. /* Scope */
  203. UdpScope::Send(0, adc_stDownOut.slSampIcPu, adc_stUpOut.swCalibIcPu, adc_stDownOut.swIcPu);
  204. //UdpScope::Send(0, scm_uwSpdFbkLpfAbsPu, pwm_stGenOut.blSampleCalibFlag);
  205. /* Determine whether the unit test pass */
  206. if (prdCnt > (loopNum / HW_PWM_PERIOD - 5))
  207. {
  208. if (!adc_stCof.blCalibCalFlag)
  209. {
  210. if(adc_stDownOut.ulISamplePeakPu > 32767)
  211. {
  212. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 780 / 1024, adc_stDownOut.swIaPu, 10); ///< 系数为立即数,程序中更改后测试用例需要随之更改
  213. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 780 / 1024, adc_stDownOut.swIbPu, 10);
  214. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 780 / 1024, adc_stDownOut.swIcPu, 10);
  215. }
  216. // else if(adc_stDownOut.ulISamplePeakPu > 25800)
  217. // {
  218. // EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 1024 / 1024, adc_stDownOut.swIaPu, 10); ///< 系数为立即数,程序中更改后测试用例需要随之更改
  219. // EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 1024 / 1024, adc_stDownOut.swIbPu, 10);
  220. // EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 1024 / 1024, adc_stDownOut.swIcPu, 10);
  221. // }
  222. else
  223. {
  224. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 1024 / 1024, adc_stDownOut.swIaPu, 10); ///< 系数为立即数,程序中更改后测试用例需要随之更改
  225. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 1024 / 1024, adc_stDownOut.swIbPu, 10);
  226. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 1024 / 1024, adc_stDownOut.swIcPu, 10);
  227. }
  228. }
  229. else
  230. {
  231. if (1024 / rdsonCoef < adc_stCof.uwCalibcoefMin)
  232. {
  233. if (currentMod * rdsonCoef * 100 >= ADC_IPHASE_CUR_MAX_AP)
  234. {
  235. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * 780 / 1024, adc_stDownOut.swIaPu, 50);
  236. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * 780 / 1024, adc_stDownOut.swIbPu, 50);
  237. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * 780 / 1024, adc_stDownOut.swIcPu, 50);
  238. }
  239. else
  240. {
  241. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * adc_stCof.uwCalibcoefMin / 1024, adc_stDownOut.swIaPu, 10);
  242. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * adc_stCof.uwCalibcoefMin / 1024, adc_stDownOut.swIbPu, 10);
  243. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * adc_stCof.uwCalibcoefMin / 1024, adc_stDownOut.swIcPu, 10);
  244. }
  245. }
  246. else if (1024 / rdsonCoef > adc_stCof.uwCalibcoefMax)
  247. {
  248. EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIaPu, 50);
  249. EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIbPu, 50);
  250. EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIcPu, 50);
  251. }
  252. else
  253. {
  254. if (currentMod < 20)
  255. {
  256. EXPECT_NEAR(ia * 100 * 16384 / IBASE, adc_stDownOut.swIaPu, 0.5 * 100 * 16384 / IBASE);
  257. EXPECT_NEAR(ib * 100 * 16384 / IBASE, adc_stDownOut.swIbPu, 0.5 * 100 * 16384 / IBASE);
  258. EXPECT_NEAR(ic * 100 * 16384 / IBASE, adc_stDownOut.swIcPu, 0.5 * 100 * 16384 / IBASE);
  259. }
  260. else
  261. {
  262. EXPECT_NEAR(ia * 100 * 16384 / IBASE, adc_stDownOut.swIaPu, 1.5 * 100 * 16384 / IBASE);
  263. EXPECT_NEAR(ib * 100 * 16384 / IBASE, adc_stDownOut.swIbPu, 1.5 * 100 * 16384 / IBASE);
  264. EXPECT_NEAR(ic * 100 * 16384 / IBASE, adc_stDownOut.swIcPu, 1.5 * 100 * 16384 / IBASE);
  265. }
  266. }
  267. }
  268. }
  269. }
  270. testTimerIntFlg[TIMER0][TIMER_INT_FLAG_UP] = 0;
  271. }
  272. }
  273. }
  274. INSTANTIATE_TEST_SUITE_P(DiffCurMod, CurSampleCalibTest1,
  275. ::testing::Combine(::testing::Values(5, 19, 39, 55), ::testing::Values(0.4, 0.8, 2.1, 6), ::testing::Values(1, 2, 10)));