spi_master.c 19 KB

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