spi_master.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  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 : STM32F30x
  8. *************************************************************************
  9. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  10. All rights reserved.
  11. *************************************************************************
  12. *************************************************************************
  13. Revising History (ECL of this file):
  14. M0_20170410, by liyue, create this file;
  15. ************************************************************************/
  16. /************************************************************************
  17. Beginning of File, do not put anything above here except notes
  18. Compiler Directives:
  19. *************************************************************************/
  20. #ifndef _SPI_MASTER_C_
  21. #define _SPI_MASTER_C_
  22. #endif
  23. /************************************************************************
  24. Included File
  25. *************************************************************************/
  26. #include "syspar.h"
  27. #include "user.h"
  28. #include "spi_master.h"
  29. /*************************************************************************
  30. Exported Functions (N/A)
  31. *************************************************************************/
  32. /*************************************************************************
  33. Function:
  34. Description:
  35. Call by:
  36. Input Variables:
  37. Output/Return Variables:
  38. Subroutine Call:
  39. Reference:
  40. *************************************************************************/
  41. void spi_voResolverInit(void)
  42. {
  43. spi_stResolverOut.uwSpiThetaTmpZ1Pu = 0;
  44. spi_stResolverOut.swSpdTmpPu = 0;
  45. spi_stResolverOut.swSpdLpfTmpPu = 0;
  46. spi_stResolverOut.swSpdLpfTmpZ1Pu = 0;
  47. spi_stResolverOut.uwSpiThetaPu = 0;
  48. spi_stResolverOut.uwSpiOrignData = 0;
  49. spi_stResolverOut.slPllThetaPu = 0;
  50. spi_stResolverOut.uwPllThetaPu = 0;
  51. spi_stResolverOut.slThetaErrPu = 0;
  52. spi_stResolverOut.slThetaErrZ1Pu = 0;
  53. spi_stResolverOut.slThetaDeltaErrPu = 0;
  54. spi_stResolverOut.swSpdFbkPu = 0;
  55. spi_stResolverOut.slSpdFbkPu = 0;
  56. spi_stResolverOut.swSpdFbkLpfPu = 0;
  57. }
  58. /*************************************************************************
  59. Function:
  60. Description:
  61. Call by:
  62. Input Variables:
  63. Output/Return Variables:
  64. Subroutine Call:
  65. Reference:
  66. *************************************************************************/
  67. void spi_voResolverCoef(SPI_RESOLVER_COEFIN *in, SPI_RESOLVER_COEF *out)
  68. {
  69. UWORD uwMvcPu;
  70. ULONG ulDamper;
  71. UWORD uwDamper;
  72. if (in->uwFbHz < 10)
  73. {
  74. in->uwFbHz = 10;
  75. }
  76. else if (in->uwFbHz > 10000)
  77. {
  78. in->uwFbHz = 10000;
  79. }
  80. if (in->uwFreqTbcHz < 10)
  81. {
  82. in->uwFreqTbcHz = 10;
  83. }
  84. if (in->uwSpdPllMcoef > 100)
  85. {
  86. in->uwSpdPllMcoef = 100;
  87. }
  88. out->uwCurTs = ((ULONG)in->uwFbHz << 10) / in->uwFreqTbcHz; // Q10, TBC time
  89. out->uwCurTsPu = ((ULONG)205887 * in->uwFbHz) / in->uwFreqTbcHz; // Q15, Q15(2pi)-->205887
  90. // /************************Speed PLL Coefficient*****************************/
  91. // out->uwSpdPllKpPu = in->uwSpdPllKpPu; //Q14
  92. // out->uwSpdPllKiPu = in->uwSpdPllKiPu; //Q14
  93. //
  94. /************************Speed PLL Coefficient*****************************/
  95. uwMvcPu = ((ULONG)in->uwSpdPllWvcHz << 10) / in->uwFbHz; // Q10
  96. /* PLL Kp=M*w/sqrt(1+M^2) */
  97. ulDamper = (1 + in->uwSpdPllMcoef * in->uwSpdPllMcoef) << 8; // Q8
  98. uwDamper = mth_slSqrt(ulDamper); // Q4
  99. out->uwSpdPllKpPu = ((ULONG)in->uwSpdPllMcoef * uwMvcPu / uwDamper) << 8; // Q10-Q4+Q8=Q14
  100. /* PLL Ki=w^2*T_cnt_ctrl/sqrt(1+M^2) */
  101. out->uwSpdPllKiPu = ((((ULONG)uwMvcPu * out->uwCurTsPu) / uwDamper) * uwMvcPu) >> 17; // Q10+Q15-Q4+Q10-Q17=Q14
  102. }
  103. /*************************************************************************
  104. Function:
  105. Description:
  106. Call by:
  107. Input Variables:
  108. Output/Return Variables:
  109. Subroutine Call:
  110. Reference:
  111. *************************************************************************/
  112. void spi_voMagneticDetection()
  113. {
  114. // UBYTE MGL, MGH;
  115. // MGL = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0);
  116. // MGH = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1);
  117. // if ((MGL != 0) || (MGH != 0))
  118. // {
  119. // blMagRangeFltFlg = TRUE;
  120. // }
  121. }
  122. /*************************************************************************
  123. Function:
  124. Description:
  125. Call by:
  126. Input Variables:
  127. Output/Return Variables:
  128. Subroutine Call:
  129. Reference:
  130. *************************************************************************/
  131. SLONG spi_pvt_slSpdFbkLpfPu, spi_pvt_slSpdLpfTmpPu;
  132. UWORD TstCnt = 0;
  133. UWORD TstThetaZ1Pu;
  134. SWORD TstSpdPu;
  135. UWORD DATA = 0;
  136. UWORD LASTDATA = 0;
  137. SWORD DATAERROR = 0;
  138. SWORD SPICNT = 0;
  139. UWORD THETACHANGE = 0;
  140. UWORD THETACHANGELast = 0;
  141. void spi_voResolver(SPI_RESOLVER_COEF *coef, SPI_RESOLVER_OUT *out)
  142. {
  143. UWORD uwSpiThetaTmpPu, uwSpiThetaTmpPu2;
  144. SWORD swThetaErrPu, swThetaCompPu;
  145. SWORD swSpdErrPu;
  146. ULONG ulTmp1, ulTmp2;
  147. if (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == SET)
  148. {
  149. uwSpiThetaTmpPu = ((SLONG)(SPI_I2S_ReceiveData(SPI3))) >> 1;
  150. uwSpiThetaTmpPu &= 0x7FF8;
  151. uwSpiThetaTmpPu2 = uwSpiThetaTmpPu;
  152. ///////////////////////////////////////////////////////////////////////////////////
  153. // UWORD FLAG = 0;
  154. // SWORD JUDGEError = 0;
  155. // LASTDATA = DATA;
  156. // JUDGEError = uwSpiThetaTmpPu - out->swSpiThetaOffset2Pu;
  157. // if(JUDGEError < 0)
  158. // {
  159. // FLAG = 1;
  160. // }
  161. // if(JUDGEError >= 0 )
  162. // {
  163. // FLAG = 0;
  164. // }
  165. // DATA = (ULONG)uwSpiThetaTmpPu + FLAG*32768 - out->swSpiThetaOffset2Pu;
  166. // DATAERROR = ((SWORD)DATA - (SWORD)LASTDATA);
  167. // if(DATAERROR < -16384)
  168. // {
  169. // SPICNT ++;
  170. // if(SPICNT == 5)
  171. // {
  172. // SPICNT=0;
  173. // }
  174. // }
  175. //
  176. // if(DATAERROR > 16384)
  177. // {
  178. // SPICNT--;
  179. // if(SPICNT<0)
  180. // {
  181. // SPICNT = 4;
  182. // }
  183. // }
  184. //
  185. // UWORD PERCENT = 0;
  186. // ULONG thetaFive2Seven = 0;
  187. // PERCENT = ((ULONG)72 * uwSpiThetaTmpPu / 32768) + SPICNT * 72;
  188. // thetaFive2Seven = ((SQWORD)32768 * 7 / 360) * PERCENT; //((SQWORD)32768 * 7 * PERCENT / (360 * 5))
  189. // while(thetaFive2Seven > 32768)
  190. // {
  191. // thetaFive2Seven = thetaFive2Seven - 32768;
  192. // }
  193. // THETACHANGELast = THETACHANGE;
  194. // THETACHANGE = (UWORD)thetaFive2Seven;
  195. /////////////////////////////////////////////////////////////////////////////////////
  196. swThetaCompPu = ((SLONG)out->swSpdLpfTmpPu * TLatency_TM) >> 10; // Q15, Consider decoding and SPI Latency:10us
  197. ulTmp1 = uwSpiThetaTmpPu + swThetaCompPu + out->swSpiThetaOffsetPu + cof_sl720DegreePu;
  198. uwSpiThetaTmpPu = ulTmp1 & 0x7FFF;
  199. ulTmp2 = uwSpiThetaTmpPu2 + cof_sl720DegreePu;
  200. uwSpiThetaTmpPu2 = ulTmp2 & 0x7FFF;
  201. out->uwSpiOrignData = uwSpiThetaTmpPu2;
  202. /* Judge the correctness of data*/
  203. swThetaErrPu = uwSpiThetaTmpPu - out->uwSpiThetaTmpZ1Pu;
  204. out->uwSpiThetaTmpZ1Pu = uwSpiThetaTmpPu;
  205. if (swThetaErrPu <= -cof_sl180DegreePu)
  206. {
  207. swThetaErrPu += cof_sl360DegreePu;
  208. }
  209. if (swThetaErrPu >= cof_sl180DegreePu)
  210. {
  211. swThetaErrPu -= cof_sl360DegreePu;
  212. }
  213. // out->swSpdTmpPu = swThetaErrPu * 14629>>12; // Q15, f_tbs/fbase*2^12=14629
  214. // out->swSpdTmpPu = swThetaErrPu * 58516>>12; // Q15, f_tbc/fbase*2^12=58516,f_tbc=10000;
  215. out->swSpdTmpPu = ((SLONG)swThetaErrPu * DIFF_COEF_TBC) >> 10; // Q15
  216. spi_pvt_slSpdLpfTmpPu = (SLONG)0x0277 * (out->swSpdTmpPu - out->swSpdLpfTmpPu) + spi_pvt_slSpdLpfTmpPu; // 50Hz Q30
  217. out->swSpdLpfTmpPu = spi_pvt_slSpdLpfTmpPu >> 15;
  218. swSpdErrPu = out->swSpdLpfTmpPu - out->swSpdLpfTmpZ1Pu;
  219. out->swSpdLpfTmpZ1Pu = out->swSpdLpfTmpPu;
  220. // spi_pvt_slSpdLpfTmpPu = 3*out->swSpdTmpPu/10 + 7*out->swSpdLpfTmpPu/10;
  221. // out->swSpdLpfTmpZ1Pu = spi_pvt_slSpdLpfTmpPu ;
  222. if ((swSpdErrPu < 6515) && (swSpdErrPu > -6515)) // 20deg electrical angle, ? rpm
  223. {
  224. out->uwSpiThetaPu = uwSpiThetaTmpPu;
  225. }
  226. else
  227. {
  228. blSpiThetaFltFlg = TRUE;
  229. }
  230. }
  231. else
  232. {
  233. blSpiThetaFltFlg = TRUE;
  234. }
  235. // TstCnt ++;
  236. // if(TstCnt > 3)
  237. // {
  238. // TstCnt =0;
  239. // TstSpdPu = ((SLONG)(out->uwSpiThetaPu - TstThetaZ1Pu) * DIFF_COEF_TBS) >>10;
  240. // TstThetaZ1Pu = out->uwSpiThetaPu;
  241. // }
  242. out->swSpdFbkPu = out->swSpdTmpPu;
  243. // /*Calculate speed: PLL method*/
  244. // out->slThetaErrPu = (SLONG)out->uwSpiThetaPu - (out->uwPllThetaPu + (((SLONG)out->swSpdFbkLpfPu * TBC_TM) >> 10));
  245. // if (out->slThetaErrPu >= cof_sl180DegreePu)
  246. // {
  247. // out->slThetaErrPu -= cof_sl360DegreePu;
  248. // }
  249. // if(out->slThetaErrPu <= -cof_sl180DegreePu)
  250. // {
  251. // out->slThetaErrPu += cof_sl360DegreePu;
  252. // }
  253. // out->slThetaDeltaErrPu = out->slThetaErrPu - out->slThetaErrZ1Pu;
  254. // out->slThetaErrZ1Pu = out->slThetaErrPu;
  255. // slKpTmpPu = out->slThetaDeltaErrPu * coef->uwSpdPllKpPu; //Q15+Q10=Q25
  256. // slKitTmpPu = out->slThetaErrPu * coef->uwSpdPllKiPu;
  257. // slSpdFbkPu = slKpTmpPu + slKitTmpPu + out->slSpdFbkPu;
  258. // /* Limit the speed value to avoid overflow */
  259. // if(slSpdFbkPu >= 0x20000000)
  260. // {
  261. // slSpdFbkPu = 0x20000000-1; //Q29
  262. // }
  263. // if(slSpdFbkPu <= -0x20000000)
  264. // {
  265. // slSpdFbkPu = -0x20000000; //Q29
  266. // }
  267. // out->slSpdFbkPu = slSpdFbkPu; //Q29
  268. // //Q29 out->swSpdFbkPu = slSpdFbkPu >> 14; //Q15
  269. //
  270. // slPllThetaPu = out->slPllThetaPu + (((SLONG)out->swSpdFbkPu * coef->uwCurTs)<<4); //Q15+Q10+Q4=Q29
  271. // if(slPllThetaPu >= 0x20000000)
  272. // {
  273. // slPllThetaPu -= 0x20000000;
  274. // }
  275. // if(slPllThetaPu < 0)
  276. // {
  277. // slPllThetaPu += 0x20000000;
  278. // }
  279. // out->slPllThetaPu = slPllThetaPu;
  280. // out->uwPllThetaPu = slPllThetaPu >> 14; //Q15 = Q29 - Q14
  281. //// spi_pvt_slSpdFbkLpfPu = (SLONG)0x00FF * (out->swSpdFbkPu - out->swSpdFbkLpfPu) + spi_pvt_slSpdFbkLpfPu; //20Hz Q30
  282. //// out->swSpdFbkLpfPu = spi_pvt_slSpdFbkLpfPu >> 15;
  283. }
  284. /*************************************************************************
  285. Function:
  286. Description:
  287. Call by:
  288. Input Variables:
  289. Output/Return Variables:
  290. Subroutine Call:
  291. Reference:
  292. *************************************************************************/
  293. void spi_voResolverLock()
  294. {
  295. /* SPI1 resolver enable */
  296. // SPI_Cmd(SPI3,ENABLE);
  297. /* CS signal enable */
  298. IO_SPI3_NSS_ENABLE;
  299. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  300. {}
  301. SPI_I2S_SendData(SPI3, 0x0550);
  302. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) == SET)
  303. {}
  304. // SPI_Cmd(SPI3,DISABLE);
  305. IO_SPI3_NSS_DISABLE;
  306. }
  307. /*************************************************************************
  308. Function:
  309. Description:
  310. Call by:
  311. Input Variables:
  312. Output/Return Variables:
  313. Subroutine Call:
  314. Reference:
  315. *************************************************************************/
  316. void spi_voReadWriteSeneorReg(void)
  317. {
  318. UWORD uwReadBCTReg = 0, uwReadETXY = 0;
  319. UWORD uwWriteBCTReg = 0, uwWriteETXY = 0;
  320. _Bool blReadCorrectFlg = FALSE, blWriteFinishFlg = FALSE;
  321. UWORD SPI_DelayCnt1 = 0, SPI_DelayCnt2 = 0;
  322. // /* SPI1 resolver enable */
  323. // SPI_Cmd(SPI3,ENABLE);
  324. /*Write command of read the BCT register value */
  325. IO_SPI3_NSS_ENABLE; /*!< CS signal enable,for data update*/
  326. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  327. {}
  328. SPI_I2S_SendData(SPI3, 0x4200); // comp value
  329. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  330. {}
  331. IO_SPI3_NSS_DISABLE;
  332. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  333. {}
  334. uwReadBCTReg = SPI_I2S_ReceiveData(SPI3); /*!< Read the first time*/
  335. IO_SPI3_NSS_ENABLE;
  336. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  337. {}
  338. SPI_I2S_SendData(SPI3, 0x0000); /*!< Write the second time*/
  339. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  340. {}
  341. IO_SPI3_NSS_DISABLE;
  342. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  343. {}
  344. uwReadBCTReg = SPI_I2S_ReceiveData(SPI3); /*!< Read the BCT register value*/
  345. /*Write command of read the ETX ETY value */
  346. IO_SPI3_NSS_ENABLE;
  347. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  348. {}
  349. SPI_I2S_SendData(SPI3, 0x4300); // comp direction
  350. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  351. {}
  352. IO_SPI3_NSS_DISABLE;
  353. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  354. {}
  355. uwReadETXY = SPI_I2S_ReceiveData(SPI3); /*!< Read the first time*/
  356. IO_SPI3_NSS_ENABLE;
  357. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  358. {}
  359. SPI_I2S_SendData(SPI3, 0x0000); /*!< Write the second time*/
  360. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  361. {}
  362. IO_SPI3_NSS_DISABLE;
  363. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  364. {}
  365. uwReadETXY = SPI_I2S_ReceiveData(SPI3); /*!< Read the ETX ETY value*/
  366. if (uwReadBCTReg == 0x3000 && uwReadETXY == 0x0100)
  367. {
  368. blReadCorrectFlg = TRUE;
  369. }
  370. else
  371. {
  372. blReadCorrectFlg = FALSE;
  373. }
  374. if ((blReadCorrectFlg == FALSE) && (blWriteFinishFlg == FALSE))
  375. {
  376. /* Write and Read BCT value*/
  377. IO_SPI3_NSS_ENABLE; // Data update
  378. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET) // Discontinuous transmission, can not indicate send complete
  379. {}
  380. SPI_I2S_SendData(SPI3, 0x8230); // LSB,BCT=48
  381. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  382. {}
  383. IO_SPI3_NSS_DISABLE; // Data update
  384. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  385. {}
  386. uwWriteBCTReg = SPI_I2S_ReceiveData(SPI3);
  387. /*delay 22ms*/
  388. while (SPI_DelayCnt2 < 20)
  389. {
  390. SPI_DelayCnt1++;
  391. if (SPI_DelayCnt1 == 10000)
  392. {
  393. SPI_DelayCnt2++;
  394. SPI_DelayCnt1 = 0;
  395. }
  396. }
  397. IO_SPI3_NSS_ENABLE;
  398. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  399. {}
  400. SPI_I2S_SendData(SPI3, 0x0000);
  401. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  402. {}
  403. IO_SPI3_NSS_DISABLE;
  404. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  405. {}
  406. uwWriteBCTReg = SPI_I2S_ReceiveData(SPI3);
  407. /* Write and Read ETX or ETY */
  408. IO_SPI3_NSS_ENABLE;
  409. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  410. {}
  411. SPI_I2S_SendData(SPI3, 0x8301);
  412. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  413. {}
  414. IO_SPI3_NSS_DISABLE;
  415. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  416. {}
  417. uwWriteETXY = SPI_I2S_ReceiveData(SPI3);
  418. /*delay 22ms*/
  419. SPI_DelayCnt2 = 0;
  420. while (SPI_DelayCnt2 < 20)
  421. {
  422. SPI_DelayCnt1++;
  423. if (SPI_DelayCnt1 == 10000)
  424. {
  425. SPI_DelayCnt2++;
  426. SPI_DelayCnt1 = 0;
  427. }
  428. }
  429. IO_SPI3_NSS_ENABLE;
  430. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  431. {}
  432. SPI_I2S_SendData(SPI3, 0x0000);
  433. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  434. {}
  435. IO_SPI3_NSS_DISABLE;
  436. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  437. {}
  438. uwWriteETXY = SPI_I2S_ReceiveData(SPI3);
  439. if (uwWriteBCTReg == 0x3000 && uwWriteETXY == 0x0100) // MSB,BCT=48
  440. {
  441. blWriteFinishFlg = TRUE; // Stored in EEPROM
  442. }
  443. else
  444. {
  445. blWriteFinishFlg = FALSE;
  446. }
  447. }
  448. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  449. {}
  450. IO_SPI3_NSS_DISABLE;
  451. /* Write and Read RD value*/
  452. IO_SPI3_NSS_ENABLE;
  453. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  454. {}
  455. SPI_I2S_SendData(SPI3, 0x8980); // RD=1,Counterclockwise 8980; RD=0,Clockwise 8900
  456. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  457. {}
  458. IO_SPI3_NSS_DISABLE;
  459. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  460. {}
  461. /*delay 22ms*/
  462. SPI_DelayCnt2 = 0;
  463. while (SPI_DelayCnt2 < 20)
  464. {
  465. SPI_DelayCnt1++;
  466. if (SPI_DelayCnt1 == 10000)
  467. {
  468. SPI_DelayCnt2++;
  469. SPI_DelayCnt1 = 0;
  470. }
  471. }
  472. IO_SPI3_NSS_ENABLE;
  473. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != SET)
  474. {}
  475. SPI_I2S_SendData(SPI3, 0x0000);
  476. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) != RESET)
  477. {}
  478. IO_SPI3_NSS_DISABLE;
  479. while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) != SET)
  480. {}
  481. // SPI_Cmd(SPI3,DISABLE);
  482. }
  483. /*************************************************************************
  484. Local Functions (N/A)
  485. *************************************************************************/
  486. /*************************************************************************
  487. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  488. All rights reserved.
  489. *************************************************************************/
  490. #ifdef _SPI_MASTER_C_
  491. #undef _SPI_MASTER_C_
  492. #endif
  493. /*************************************************************************
  494. End of this File (EOF)!
  495. Do not put anything after this part!
  496. *************************************************************************/