spi_master.c 18 KB

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