spi_master.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: spi_master.c
  4. Partner Filename: spi_master.h
  5. Description: SPI master driver
  6. Complier: IAR Embedded Workbench for ARM 8.40.2
  7. CPU TYPE : GD32F30x
  8. *************************************************************************
  9. Copyright (c) 2022 Welling Motor Technology(Shanghai) Co. Ltd.
  10. All rights reserved.
  11. *************************************************************************
  12. *************************************************************************
  13. Revising History (ECL of this file):
  14. ************************************************************************/
  15. /************************************************************************
  16. Beginning of File, do not put anything above here except notes
  17. Compiler Directives:
  18. *************************************************************************/
  19. #ifndef _SPI_MASTER_C_
  20. #define _SPI_MASTER_C_
  21. #endif
  22. /************************************************************************
  23. Included File
  24. *************************************************************************/
  25. #include "syspar.h"
  26. #include "user.h"
  27. /*************************************************************************
  28. Exported Functions (N/A)
  29. *************************************************************************/
  30. /*************************************************************************
  31. Function:
  32. Description:
  33. Call by:
  34. Input Variables:
  35. Output/Return Variables:
  36. Subroutine Call:
  37. Reference:
  38. *************************************************************************/
  39. void spi_voResolverInit(void)
  40. {
  41. spi_stResolverOut.uwSpiThetaTmpZ1Pu = 0;
  42. spi_stResolverOut.swSpdLpfTmpPu = 0;
  43. spi_stResolverOut.swSpdLpfTmpZ1Pu = 0;
  44. spi_stResolverOut.uwSpiThetaPu = 0;
  45. spi_stResolverOut.uwSpiOrignData = 0;
  46. spi_stResolverOut.slPllThetaPu = 0;
  47. spi_stResolverOut.uwPllThetaPu = 0;
  48. spi_stResolverOut.slThetaErrPu = 0;
  49. spi_stResolverOut.slThetaErrZ1Pu = 0;
  50. spi_stResolverOut.slThetaDeltaErrPu = 0;
  51. spi_stResolverOut.swSpdFbkPu = 0;
  52. spi_stResolverOut.swPllSpdFbkPu = 0;
  53. spi_stResolverOut.slPllSpdFbkPu = 0;
  54. spi_stResolverOut.swSpdFbkLpfPu = 0;
  55. }
  56. /*************************************************************************
  57. Function:
  58. Description:
  59. Call by:
  60. Input Variables:
  61. Output/Return Variables:
  62. Subroutine Call:
  63. Reference:
  64. *************************************************************************/
  65. void spi_voResolverCoef(SPI_RESOLVER_COEFIN *in, SPI_RESOLVER_COEF *out)
  66. {
  67. UWORD uwMvcPu;
  68. ULONG ulDamper;
  69. UWORD uwDamper;
  70. if (in->uwFbHz < 10)
  71. {
  72. in->uwFbHz = 10;
  73. }
  74. else if (in->uwFbHz > 10000)
  75. {
  76. in->uwFbHz = 10000;
  77. }
  78. if (in->uwFreqTbcHz < 10)
  79. {
  80. in->uwFreqTbcHz = 10;
  81. }
  82. if (in->uwSpdPllMcoef > 100)
  83. {
  84. in->uwSpdPllMcoef = 100;
  85. }
  86. out->uwCurTs = ((ULONG)in->uwFbHz << 10) / in->uwFreqTbcHz; // Q10, TBC time
  87. out->uwCurTsPu = ((ULONG)205887 * in->uwFbHz) / in->uwFreqTbcHz; // Q15, Q15(2pi)-->205887
  88. // /************************Speed PLL Coefficient*****************************/
  89. // out->uwSpdPllKpPu = in->uwSpdPllKpPu; //Q14
  90. // out->uwSpdPllKiPu = in->uwSpdPllKiPu; //Q14
  91. /************************Speed PLL Coefficient*****************************/
  92. uwMvcPu = ((ULONG)in->uwSpdPllWvcHz << 10) / in->uwFbHz; // Q10
  93. /* PLL Kp=M*w/sqrt(1+M^2) */
  94. ulDamper = (1 + in->uwSpdPllMcoef * in->uwSpdPllMcoef) << 8; // Q8
  95. uwDamper = mth_slSqrt(ulDamper); // Q4
  96. out->uwSpdPllKpPu = ((ULONG)in->uwSpdPllMcoef * uwMvcPu / uwDamper) << 8; // Q10-Q4+Q8=Q14
  97. /* PLL Ki=w^2*T_cnt_ctrl/sqrt(1+M^2) */
  98. out->uwSpdPllKiPu = ((((ULONG)uwMvcPu * out->uwCurTsPu) / uwDamper) * uwMvcPu) >> 17; // Q10+Q15-Q4+Q10-Q17=Q14
  99. }
  100. /*************************************************************************
  101. Function:
  102. Description:
  103. Call by:
  104. Input Variables:
  105. Output/Return Variables:
  106. Subroutine Call:
  107. Reference:
  108. *************************************************************************/
  109. void spi_voMagneticDetection()
  110. {
  111. UWORD MGL, MGH;
  112. MGL = gpio_input_bit_get(GPIOB, GPIO_PIN_0);
  113. MGH = gpio_input_bit_get(GPIOB, GPIO_PIN_1);
  114. if ((MGL != 0) || (MGH != 0))
  115. {
  116. spi_stResolverOut.blMagRangeFltFlg = TRUE; // ! can not indicate magnet range fault
  117. }
  118. else
  119. {
  120. spi_stResolverOut.blMagRangeFltFlg = FALSE;
  121. }
  122. }
  123. /*************************************************************************
  124. Function:
  125. Description:
  126. Call by:
  127. Input Variables:
  128. Output/Return Variables:
  129. Subroutine Call:
  130. Reference:
  131. *************************************************************************/
  132. SLONG spi_pvt_slSpdFbkLpfPu, spi_pvt_slSpdLpfTmpPu;
  133. void spi_voResolver(SPI_RESOLVER_COEF *coef, SPI_RESOLVER_OUT *out)
  134. {
  135. UWORD uwSpiThetaTmpPu = 0, uwSpiThetaTmpPu2 = 0;
  136. SWORD swThetaErrPu = 0, swThetaCompPu = 0;
  137. SWORD swSpdTmpPu = 0, swSpdErrPu = 0;
  138. ULONG ulTmp1 = 0, ulTmp2 = 0;
  139. if (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) == SET)
  140. {
  141. uwSpiThetaTmpPu = ((SLONG)(spi_i2s_data_receive(SPI2))) >> 1;
  142. uwSpiThetaTmpPu &= 0x7FF8;
  143. uwSpiThetaTmpPu2 = uwSpiThetaTmpPu;
  144. swThetaCompPu = ((SLONG)out->swSpdLpfTmpPu * TLatency_TM) >> 10; // Q15, Consider decoding and SPI Latency:10us
  145. ulTmp1 = uwSpiThetaTmpPu + swThetaCompPu + out->swSpiThetaOffsetPu + cof_sl720DegreePu;
  146. uwSpiThetaTmpPu = ulTmp1 & 0x7FFF;
  147. ulTmp2 = uwSpiThetaTmpPu2 + cof_sl720DegreePu;
  148. uwSpiThetaTmpPu2 = ulTmp2 & 0x7FFF;
  149. out->uwSpiOrignData = uwSpiThetaTmpPu2;
  150. /* Calculate speed: Differentiation method */
  151. swThetaErrPu = uwSpiThetaTmpPu - out->uwSpiThetaTmpZ1Pu;
  152. out->uwSpiThetaTmpZ1Pu = uwSpiThetaTmpPu;
  153. if (swThetaErrPu <= -cof_sl180DegreePu)
  154. {
  155. swThetaErrPu += cof_sl360DegreePu;
  156. }
  157. if (swThetaErrPu >= cof_sl180DegreePu)
  158. {
  159. swThetaErrPu -= cof_sl360DegreePu;
  160. }
  161. swSpdTmpPu = ((SLONG)swThetaErrPu * DIFF_COEF_TBC) >> 10; // Q15
  162. /* Judge the correctness of spi position*/
  163. spi_pvt_slSpdLpfTmpPu = (SLONG)0x0277 * (swSpdTmpPu - out->swSpdLpfTmpPu) + spi_pvt_slSpdLpfTmpPu; // 50Hz Q30
  164. out->swSpdLpfTmpPu = spi_pvt_slSpdLpfTmpPu >> 15;
  165. swSpdErrPu = out->swSpdLpfTmpPu - out->swSpdLpfTmpZ1Pu;
  166. out->swSpdLpfTmpZ1Pu = out->swSpdLpfTmpPu;
  167. if ((swSpdErrPu < USER_MOTOR_1000RPM2PU) && (swSpdErrPu > -USER_MOTOR_1000RPM2PU))
  168. {
  169. out->uwSpiThetaPu = uwSpiThetaTmpPu;
  170. out->blSpiThetaFltFlg = FALSE;
  171. }
  172. else
  173. {
  174. out->blSpiThetaFltFlg = TRUE;
  175. }
  176. }
  177. else
  178. {
  179. out->blSpiThetaFltFlg = TRUE;
  180. }
  181. out->swSpdFbkPu = swSpdTmpPu;
  182. /*Calculate speed: PLL method*/
  183. SLONG slThetaErrPu,slThetaDeltaErrPu,slPllThetaPu;
  184. SLONG slKpTmpPu,slKitTmpPu,slPllSpdFbkPu;
  185. ULONG ulSpdPllKpPu,ulSpdPllKiPu;
  186. slThetaErrPu = (SLONG)out->uwSpiThetaPu - (out->uwPllThetaPu + (((SLONG)out->swPllSpdFbkPu * coef->uwCurTs) >> 10)); //Q15
  187. if (slThetaErrPu >= cof_sl180DegreePu)
  188. {
  189. slThetaErrPu-= cof_sl360DegreePu;
  190. }
  191. if(slThetaErrPu <= -cof_sl180DegreePu)
  192. {
  193. slThetaErrPu += cof_sl360DegreePu;
  194. }
  195. slThetaDeltaErrPu = slThetaErrPu - out->slThetaErrZ1Pu;
  196. out->slThetaErrZ1Pu = slThetaErrPu;
  197. /* Variable parameter PI,untested*/
  198. // if(out->swPllSpdFbkPu < cof_uw1000RpmPu - cof_uw200RpmPu)
  199. // {
  200. // ulSpdPllKpPu = coef->uwSpdPllKpPu;
  201. // ulSpdPllKiPu = coef->uwSpdPllKiPu;
  202. // }
  203. // else if((out->swPllSpdFbkPu > cof_uw1000RpmPu) && (out->swPllSpdFbkPu < cof_uw2000RpmPu - cof_uw200RpmPu))
  204. // {
  205. // ulSpdPllKpPu = coef->uwSpdPllKpPu * 2;
  206. // ulSpdPllKiPu = coef->uwSpdPllKiPu * 2 * 2;
  207. // }
  208. // else if((out->swPllSpdFbkPu > cof_uw2000RpmPu) && (out->swPllSpdFbkPu < cof_uw3000RpmPu - cof_uw200RpmPu))
  209. // {
  210. // ulSpdPllKpPu = coef->uwSpdPllKpPu * 4;
  211. // ulSpdPllKiPu = coef->uwSpdPllKiPu * 4 * 4;
  212. // }
  213. // else if((out->swPllSpdFbkPu > cof_uw3000RpmPu) && (out->swPllSpdFbkPu < cof_uw4000RpmPu - cof_uw200RpmPu))
  214. // {
  215. // ulSpdPllKpPu = coef->uwSpdPllKpPu * 8;
  216. // ulSpdPllKiPu = coef->uwSpdPllKiPu * 8 * 8;
  217. // }
  218. // else if (out->swPllSpdFbkPu > cof_uw4000RpmPu)
  219. // {
  220. // ulSpdPllKpPu = coef->uwSpdPllKpPu * 16;
  221. // ulSpdPllKiPu = coef->uwSpdPllKiPu * 16 * 16;
  222. // }
  223. ulSpdPllKpPu = coef->uwSpdPllKpPu;
  224. ulSpdPllKiPu = coef->uwSpdPllKiPu;
  225. slKpTmpPu = slThetaDeltaErrPu * ulSpdPllKpPu; //Q15+Q14=Q29
  226. slKitTmpPu = slThetaErrPu * ulSpdPllKiPu;
  227. slPllSpdFbkPu = slKpTmpPu + slKitTmpPu + out->slPllSpdFbkPu;
  228. if(slPllSpdFbkPu >= 0x20000000)
  229. {
  230. slPllSpdFbkPu = 0x20000000-1; //Q29
  231. }
  232. if(slPllSpdFbkPu <= -0x20000000)
  233. {
  234. slPllSpdFbkPu = -0x20000000; //Q29
  235. }
  236. out->slPllSpdFbkPu = slPllSpdFbkPu; //Q29
  237. out->swPllSpdFbkPu = slPllSpdFbkPu >> 14; //Q15
  238. slPllThetaPu = out->slPllThetaPu + (((SLONG)out->swPllSpdFbkPu * coef->uwCurTs) << 4); //Q15+Q10+Q4=Q29
  239. if(slPllThetaPu >= 0x20000000)
  240. {
  241. slPllThetaPu -= 0x20000000;
  242. }
  243. if(slPllThetaPu < 0)
  244. {
  245. slPllThetaPu += 0x20000000;
  246. }
  247. out->slPllThetaPu = slPllThetaPu;
  248. out->uwPllThetaPu = slPllThetaPu >> 14; //Q15 = Q29 - Q14
  249. // spi_pvt_slSpdFbkLpfPu = (SLONG)0x00FF * (out->swPllSpdFbkPu - out->swSpdFbkLpfPu) + spi_pvt_slSpdFbkLpfPu; //20Hz Q30
  250. // out->swSpdFbkLpfPu = spi_pvt_slSpdFbkLpfPu >> 15;
  251. }
  252. /*************************************************************************
  253. Function:
  254. Description:
  255. Call by:
  256. Input Variables:
  257. Output/Return Variables:
  258. Subroutine Call:
  259. Reference:
  260. *************************************************************************/
  261. void spi_voResolverLock()
  262. {
  263. /* CS signal enable */
  264. IO_SPI2_NSS_ENABLE;
  265. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  266. {}
  267. spi_i2s_data_transmit(SPI2,0x0550);
  268. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TRANS) != RESET)
  269. {}
  270. /* CS signal disable */
  271. IO_SPI2_NSS_DISABLE;
  272. }
  273. /*************************************************************************
  274. Function:
  275. Description:
  276. Call by:
  277. Input Variables:
  278. Output/Return Variables:
  279. Subroutine Call:
  280. Reference:
  281. *************************************************************************/
  282. void spi_voReadWriteSeneorReg(void)
  283. {
  284. UWORD uwReadBCTReg = 0, uwReadETXY = 0;
  285. UWORD uwWriteBCTReg = 0, uwWriteETXY = 0, uwWriteRD = 0;
  286. UWORD SPI_DelayCnt1 = 0, SPI_DelayCnt2 = 0;
  287. /* Read the BCT register value */
  288. IO_SPI2_NSS_ENABLE; /*!< CS signal enable,for data update */
  289. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  290. {}
  291. spi_i2s_data_transmit(SPI2, 0x4200); //comp value
  292. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TRANS) != RESET)
  293. {}
  294. IO_SPI2_NSS_DISABLE;
  295. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  296. {}
  297. uwReadBCTReg = spi_i2s_data_receive(SPI2); /*!< Read the first time */
  298. IO_SPI2_NSS_ENABLE;
  299. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  300. {}
  301. spi_i2s_data_transmit(SPI2, 0x0000); /*!< Write the second time */
  302. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TRANS) != RESET)
  303. {}
  304. IO_SPI2_NSS_DISABLE;
  305. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  306. {}
  307. uwReadBCTReg = spi_i2s_data_receive(SPI2); /*!< Read the BCT register value */
  308. /* Read the ETX ETY value */
  309. IO_SPI2_NSS_ENABLE;
  310. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  311. {}
  312. spi_i2s_data_transmit(SPI2, 0x4300); //comp direction
  313. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TRANS) != RESET)
  314. {}
  315. IO_SPI2_NSS_DISABLE;
  316. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  317. {}
  318. uwReadETXY = spi_i2s_data_receive(SPI2); /*!< Read the first time */
  319. IO_SPI2_NSS_ENABLE;
  320. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  321. {}
  322. spi_i2s_data_transmit(SPI2, 0x0000); /*!< Write the second time */
  323. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TRANS) != RESET)
  324. {}
  325. IO_SPI2_NSS_DISABLE;
  326. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  327. {}
  328. uwReadETXY = spi_i2s_data_receive(SPI2); /*!< Read the ETX ETY value */
  329. if (uwReadBCTReg == 0x3000 && uwReadETXY == 0x0100)
  330. {
  331. spi_blReadRegCorrectFlg = TRUE;
  332. }
  333. else
  334. {
  335. spi_blReadRegCorrectFlg = FALSE;
  336. }
  337. /* Write MA702 BCT, EXY, RD Register */
  338. if ((spi_blReadRegCorrectFlg == FALSE) && (spi_blWriteRegFinishFlg == FALSE))
  339. //if (spi_blWriteRegFinishFlg == FALSE)
  340. {
  341. /* Write and Read BCT value*/
  342. IO_SPI2_NSS_ENABLE; // Data update
  343. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)// Discontinuous transmission, can not indicate send complete
  344. {}
  345. spi_i2s_data_transmit(SPI2, 0x8230); // LSB,BCT=48
  346. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  347. {}
  348. uwWriteBCTReg = spi_i2s_data_receive(SPI2);
  349. IO_SPI2_NSS_DISABLE;
  350. /* Delay at least 22ms */
  351. while (SPI_DelayCnt2 < 20)
  352. {
  353. SPI_DelayCnt1++;
  354. if (SPI_DelayCnt1 == 10000)
  355. {
  356. SPI_DelayCnt2++;
  357. SPI_DelayCnt1 = 0;
  358. }
  359. }
  360. IO_SPI2_NSS_ENABLE;
  361. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  362. {}
  363. spi_i2s_data_transmit(SPI2, 0x0000);
  364. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  365. {}
  366. uwWriteBCTReg = spi_i2s_data_receive(SPI2);
  367. IO_SPI2_NSS_DISABLE;
  368. /* Write and Read ETX or ETY */
  369. IO_SPI2_NSS_ENABLE;
  370. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  371. {}
  372. spi_i2s_data_transmit(SPI2, 0x8301);
  373. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  374. {}
  375. uwWriteETXY = spi_i2s_data_receive(SPI2);
  376. IO_SPI2_NSS_DISABLE;
  377. /* Delay at least 22ms */
  378. SPI_DelayCnt2 = 0;
  379. while (SPI_DelayCnt2 < 20)
  380. {
  381. SPI_DelayCnt1++;
  382. if (SPI_DelayCnt1 == 10000)
  383. {
  384. SPI_DelayCnt2++;
  385. SPI_DelayCnt1 = 0;
  386. }
  387. }
  388. IO_SPI2_NSS_ENABLE;
  389. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  390. {}
  391. spi_i2s_data_transmit(SPI2, 0x0000);
  392. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  393. {}
  394. uwWriteETXY = spi_i2s_data_receive(SPI2);
  395. IO_SPI2_NSS_DISABLE;
  396. /* Write and Read RD value*/
  397. IO_SPI2_NSS_ENABLE;
  398. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  399. {}
  400. spi_i2s_data_transmit(SPI2, 0x8980); // RD=1,Counterclockwise,8980; RD=0,Clockwise,8900
  401. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  402. {}
  403. uwWriteRD = spi_i2s_data_receive(SPI2);
  404. IO_SPI2_NSS_DISABLE;
  405. /* Delay at least 22ms */
  406. SPI_DelayCnt2 = 0;
  407. while (SPI_DelayCnt2 < 20)
  408. {
  409. SPI_DelayCnt1++;
  410. if (SPI_DelayCnt1 == 10000)
  411. {
  412. SPI_DelayCnt2++;
  413. SPI_DelayCnt1 = 0;
  414. }
  415. }
  416. IO_SPI2_NSS_ENABLE;
  417. while (spi_i2s_flag_get(SPI2, SPI_FLAG_TBE) != SET)
  418. {}
  419. spi_i2s_data_transmit(SPI2, 0x0000);
  420. while (spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE) != SET)
  421. {}
  422. uwWriteRD = spi_i2s_data_receive(SPI2);
  423. IO_SPI2_NSS_DISABLE;
  424. if (uwWriteBCTReg == 0x3000 && uwWriteETXY == 0x0100 && uwWriteRD == 0x8000) // MSB
  425. {
  426. spi_blWriteRegFinishFlg = TRUE; // Need stored in EEPROM
  427. }
  428. else
  429. {
  430. spi_blWriteRegFinishFlg = FALSE;
  431. }
  432. }
  433. }
  434. /*************************************************************************
  435. Local Functions (N/A)
  436. *************************************************************************/
  437. /*************************************************************************
  438. Copyright (c) 2022 Welling Motor Technology(Shanghai) Co. Ltd.
  439. All rights reserved.
  440. *************************************************************************/
  441. #ifdef _SPI_MASTER_C_
  442. #undef _SPI_MASTER_C_
  443. #endif
  444. /*************************************************************************
  445. End of this File (EOF)!
  446. Do not put anything after this part!
  447. *************************************************************************/