AngleSensor.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #include "stdio.h"
  2. #include "string.h"
  3. #include "gpio.h"
  4. #include "ac780x_spi_reg.h"
  5. #include "AngleSensor.h"
  6. #define DATA_SIZE 6U
  7. /*! SPI发送和接收数组*/
  8. uint8_t g_spiTxBuff1[DATA_SIZE] = {0};
  9. uint8_t g_spiRxBuff1[DATA_SIZE] = {0};
  10. static float angle_offset = 0.0;
  11. static float angle_raw = 0.0;
  12. /*************<prototype>**************/
  13. void SPI0_Callback(void *device, uint32_t wpara, uint32_t lpara);
  14. ERROR_Type SPI_TransmitReceivePoll_V2(SPI_Type *SPIx, uint8_t *rxBuffer, const uint8_t *txBuffer, uint32_t length, uint32_t timeout);
  15. uint8_t SPI_CRC8(uint8_t *message, uint8_t Bytelength );
  16. void AngleSensor_Init(void)
  17. {
  18. SPI_ConfigType spiConfig;
  19. /*初始化SPI引脚,功能复用选择.*/
  20. //GPIO_SetFunc(GPIOB, GPIO_PIN15, GPIO_FUN3);//SCK
  21. //GPIO_SetFunc(GPIOB, GPIO_PIN14, GPIO_FUN3);//MOSI
  22. //GPIO_SetFunc(GPIOC, GPIO_PIN0, GPIO_FUN3);//MISO
  23. //GPIO_SetFunc(GPIOC, GPIO_PIN1, GPIO_FUN3);//CS
  24. /*清零配置结构体变量.*/
  25. memset(&spiConfig, 0x00, sizeof(spiConfig));
  26. /*初始化SPI参数,波特率 = 0.8Mbps = (F_BCLK / (SCK_LOW+1 + SCK_HIGH+1)).*/
  27. spiConfig.csSetup = 4;/*片选建立时间 = (CS_SETUP + 1) * CLK_PERIOD.*/
  28. spiConfig.csHold = 4;/*片选保持时间 = (CS_HOLD + 1) * CLK_PERIOD.*/
  29. spiConfig.sckHigh = 5;/*SCK高电平时间 = (SCK_HIGH + 1) * CLK_PERIOD.*/
  30. spiConfig.sckLow = 5;/*SCK低电平时间 = (SCK_LOW + 1) * CLK_PERIOD.*/
  31. spiConfig.csIdle = 3;/*两条数据间最短时间间隔 = (CS_IDLE + 1) * CLK_PERIOD.*/
  32. spiConfig.mode = SPI_MASTER;//设置为主机模式
  33. spiConfig.cpha = SPI_CPHA_2EDGE;//设置数据采样相位,第2个边沿采样数据
  34. spiConfig.cpol = SPI_CPOL_LOW;//设置SCK空闲时极性,空闲时SCK为低
  35. spiConfig.frmSize = SPI_FRAME_SIZE_16BITS;
  36. spiConfig.rxMsbFirstEn = ENABLE;//选择从最高位开始接收
  37. spiConfig.txMsbFirstEn = ENABLE;//选择从最高位开始发送
  38. spiConfig.csOutputEn = ENABLE;//CS有SPI硬件控制
  39. spiConfig.continuousCSEn= ENABLE;//片选连续模式
  40. spiConfig.dmaRxEn = DISABLE;//禁止使用DMA接收数据
  41. spiConfig.dmaTxEn = DISABLE;//禁止使用DMA发送数据
  42. spiConfig.modeFaultEn = DISABLE;//模式故障禁止
  43. spiConfig.wakeUpEn = DISABLE;//主机模式不支持唤醒功能
  44. spiConfig.spiEn = ENABLE;
  45. spiConfig.callBack = SPI0_Callback;
  46. spiConfig.interruptEn = ENABLE;//使能NVIC中断
  47. spiConfig.txUFInterruptEn = ENABLE;//打开TXUF中断,可禁止
  48. spiConfig.rxOFInterruptEn = ENABLE;//打开RXOF中断,可禁止
  49. spiConfig.modeFaultInterruptEn = DISABLE;//模式故障中断
  50. SPI_Init(SPI0, &spiConfig);
  51. // NVIC_SetPriority(SPI0_IRQn, 1);
  52. // NVIC_ClearPendingIRQ(SPI0_IRQn);
  53. // NVIC_EnableIRQ(SPI0_IRQn);
  54. }
  55. void AngleSensor_Setoffset(float offset)
  56. {
  57. angle_offset = offset;
  58. }
  59. float AngleSensor_GetAngleInt(void)
  60. {
  61. uint16_t angle_value;
  62. float angle = 0.0;
  63. g_spiTxBuff1[0] = 0x21;
  64. g_spiTxBuff1[1] = 0x80;
  65. g_spiTxBuff1[2] = 0xFF;
  66. g_spiTxBuff1[3] = 0xFF;
  67. g_spiTxBuff1[4] = 0xFF;
  68. g_spiTxBuff1[5] = 0xFF;
  69. SPI_TransmitReceiveInt(SPI0, g_spiRxBuff1, g_spiTxBuff1, 6);
  70. while(!(SPI_GetTransmitReceiveStatus(SPI0) & SPI_STATUS_RX_FINISH_MASK))//等待读取完毕
  71. {
  72. };
  73. SPI_MasterReleaseCS(SPI0);
  74. printf("g_spiRxBuff1[0]:0x%x, g_spiRxBuff1[1]:0x%x \r\n", g_spiRxBuff1[0], g_spiRxBuff1[1]);
  75. printf("g_spiRxBuff1[2]:0x%x, g_spiRxBuff1[3]:0x%x \r\n", g_spiRxBuff1[2], g_spiRxBuff1[3]);
  76. printf("g_spiRxBuff1[4]:0x%x, g_spiRxBuff1[5]:0x%x \r\n", g_spiRxBuff1[4], g_spiRxBuff1[5]);
  77. //
  78. angle_value = g_spiRxBuff1[3]&0x7F;
  79. angle_value = (angle_value<<8)|g_spiRxBuff1[2];
  80. angle = (360.0*angle_value)/32768;
  81. if((g_spiRxBuff1[5]&0x30) != 0x30){
  82. angle = -180.0;
  83. printf("angle_raw 111 : %f \r\n", angle);
  84. }else{
  85. angle_raw = angle;
  86. printf("angle_raw 222 : %f \r\n", angle);
  87. angle += angle_offset;
  88. if(angle > 360.0){
  89. angle -= 360.0;
  90. }
  91. if(angle < 0.0){
  92. angle += 360.0;
  93. }
  94. }
  95. return angle;
  96. }
  97. float AngleSensor_GetAnglePolling(void)
  98. {
  99. uint16_t angle_value;
  100. ERROR_Type ret = SUCCESS;
  101. //uint8_t safeword =0;
  102. uint8_t crc;
  103. float angle = 0.0;
  104. g_spiTxBuff1[0] = 0x21;
  105. g_spiTxBuff1[1] = 0x80;
  106. g_spiTxBuff1[2] = 0xFF;
  107. g_spiTxBuff1[3] = 0xFF;
  108. g_spiTxBuff1[4] = 0xFF;
  109. g_spiTxBuff1[5] = 0xFF;
  110. memset(g_spiRxBuff1, 0x00, 6);
  111. ret = SPI_TransmitReceivePoll_V2(SPI0, g_spiRxBuff1, g_spiTxBuff1, 6, 2000);
  112. //ret = SPI_TransmitReceivePoll(SPI0, g_spiRxBuff1, g_spiTxBuff1, 6);
  113. if(SUCCESS == ret){
  114. //复用txbuff
  115. g_spiTxBuff1[0] = 0x80;
  116. g_spiTxBuff1[1] = 0x21;
  117. g_spiTxBuff1[2] = g_spiRxBuff1[3];
  118. g_spiTxBuff1[3] = g_spiRxBuff1[2];
  119. crc = SPI_CRC8(g_spiTxBuff1, 4);
  120. if(g_spiRxBuff1[4] == crc){
  121. // printf("crc22 %x: g_spiRxBuff1[0]:0x%x, g_spiRxBuff1[1]:0x%x \r\n", crc, g_spiRxBuff1[0], g_spiRxBuff1[1]);
  122. // printf("g_spiRxBuff1[2]:0x%x, g_spiRxBuff1[3]:0x%x \r\n", g_spiRxBuff1[2], g_spiRxBuff1[3]);
  123. // printf("g_spiRxBuff1[4]:0x%x, g_spiRxBuff1[5]:0x%x \r\n", g_spiRxBuff1[4], g_spiRxBuff1[5]);
  124. //
  125. if((g_spiRxBuff1[5]&0x30) != 0x30){
  126. // printf("angle_raw 111 : %f \r\n", angle);
  127. angle = -180.0;
  128. }else{
  129. angle_value = g_spiRxBuff1[3]&0x7F;
  130. angle_value = (angle_value<<8)|g_spiRxBuff1[2];
  131. angle = (360.0*angle_value)/32768;
  132. angle_raw = angle;
  133. // printf("angle_raw 222 : %f \r\n", angle);
  134. angle += angle_offset;
  135. if(angle > 360.0){
  136. angle -= 360.0;
  137. }
  138. if(angle < 0.0){
  139. angle += 360.0;
  140. }
  141. }
  142. }
  143. }else{
  144. angle = -180.0;
  145. }
  146. return angle;
  147. }
  148. float AngleSensor_GetAngle(void)
  149. {
  150. //return AngleSensor_GetAngleInt();
  151. return AngleSensor_GetAnglePolling();
  152. }
  153. float AngleSensor_GetAngleRaw(void)
  154. {
  155. return angle_raw;
  156. }
  157. void AngleSensor_PrintInfo(void)
  158. {
  159. printf("AngleSensor angle:%f \r\n", AngleSensor_GetAnglePolling());
  160. }
  161. void AngleSensor_DeInit(void)
  162. {
  163. SPI_DeInit(SPI0);
  164. }
  165. /**
  166. * @prototype SPI0_Callback(void *device, uint32_t wpara, uint32_t lpara)
  167. *
  168. * @param[in] ...
  169. * @return void
  170. *
  171. * @brief SPI0中断回调函数.
  172. */
  173. void SPI0_Callback(void *device, uint32_t wpara, uint32_t lpara)
  174. {
  175. if (wpara & SPI_STATUS_TXUF_Msk)
  176. {
  177. //TX下溢处理
  178. }
  179. else if (wpara & SPI_STATUS_RXOF_Msk)
  180. {
  181. //RX溢出处理
  182. }
  183. }
  184. /*!
  185. * @brief Clear SPI Tx under flow and Rx over flow status
  186. *
  187. * @param[in] SPIx: SPI type pointer,x can be 0 to 1
  188. * @return Function status
  189. * 0: ERROR, occour Tx under flow or Rx over flow flag
  190. * 1: SUCCESS, no Tx under flow and Rx over flow flag
  191. */
  192. static ERROR_Type MY_SPI_ClearTxUFRxOF(SPI_Type *SPIx)
  193. {
  194. ERROR_Type ret = SUCCESS;
  195. /* Clear Tx under flow flag */
  196. if (SPI_IsTxUF(SPIx))
  197. {
  198. SPI_ClearTxUF(SPIx);
  199. ret = ERROR;
  200. }
  201. else
  202. {
  203. /* Do nothing */
  204. }
  205. /* Clear Rx over flow flag */
  206. if (SPI_IsRxOF(SPIx))
  207. {
  208. SPI_ClearRxOF(SPIx);
  209. ret = ERROR;
  210. }
  211. else
  212. {
  213. /* Do nothing */
  214. }
  215. return ret;
  216. }
  217. /*!
  218. * @brief SPI transmission,reception by polling
  219. *
  220. * @param[in] SPIx: SPI type pointer,x can be 0 to 1
  221. * @param[in] rxBuffer: point to the receive data
  222. * @param[in] txBuffer: point to the send data
  223. * @param[in] length: transfer data length
  224. * @param[in] timeout: timeout us
  225. * @return Function status
  226. * 0: ERROR, length is 0 or rdbuff is NULL or txBuffer is NULL
  227. * 1: SUCCESS
  228. */
  229. ERROR_Type SPI_TransmitReceivePoll_V2(SPI_Type *SPIx, uint8_t *rxBuffer, const uint8_t *txBuffer, uint32_t length, uint32_t timeout)
  230. {
  231. uint32_t i = 0;
  232. uint32_t _time_us = 0;
  233. ERROR_Type ret = SUCCESS;
  234. DEVICE_ASSERT(IS_SPI_PERIPH(SPIx));
  235. if ((length == 0) || (rxBuffer == NULL) || (txBuffer == NULL))
  236. {
  237. ret = ERROR;
  238. }
  239. else
  240. {
  241. /* Disable Tx/Rx only mode */
  242. SPI_SetTxOnly(SPIx, DISABLE);
  243. SPI_SetRxOnly(SPIx, DISABLE);
  244. if ((SPI_FrameSizeType)SPI_GetFRMSize(SPIx) > SPI_FRAME_SIZE_8BITS) /* FrameSize is 9 bits ~ 16 bits */
  245. {
  246. if (((uint32_t)txBuffer & 0x01) || ((uint32_t)rxBuffer & 0x01)) /* txBuffer or rxBufer is not half-word alignment */
  247. {
  248. ret = ERROR;
  249. return ret;
  250. }
  251. length = length >> 0x01u;
  252. /* transmit and receive data */
  253. for (i = 0; i < length; i++)
  254. {
  255. while (!SPI_IsTxEF(SPIx) &&(_time_us < timeout))
  256. {
  257. udelay(1);
  258. _time_us++;
  259. }
  260. SPI_WriteDataReg(SPIx, ((uint16_t *)txBuffer)[i]);
  261. while (!SPI_IsRxFF(SPIx) &&(_time_us < timeout))
  262. {
  263. udelay(1);
  264. _time_us++;
  265. }
  266. ((uint16_t *)rxBuffer)[i] = SPI_ReadDataReg(SPIx);
  267. }
  268. }
  269. else /* FrameSize is 4 bits ~ 8 bits */
  270. {
  271. /* transmit and receive data */
  272. for (i = 0; i < length; i++)
  273. {
  274. while (!SPI_IsTxEF(SPIx) &&(_time_us < timeout))
  275. {
  276. udelay(1);
  277. _time_us++;
  278. }
  279. SPI_WriteDataReg(SPIx, txBuffer[i]);
  280. while (!SPI_IsRxFF(SPIx) &&(_time_us < timeout))
  281. {
  282. udelay(1);
  283. _time_us++;
  284. }
  285. rxBuffer[i] = (uint8_t)SPI_ReadDataReg(SPIx);
  286. }
  287. }
  288. while ((SPI_IsBusy(SPIx)));
  289. SPI_CSRelease(SPIx);
  290. }
  291. /* Check and Clear Tx under flow/ Rx over flow flag */
  292. if (MY_SPI_ClearTxUFRxOF(SPIx) == ERROR)
  293. {
  294. ret = ERROR;
  295. }
  296. else
  297. {
  298. if((_time_us >= timeout)){
  299. ret = ERROR;
  300. }
  301. /* Do nothing */
  302. }
  303. return ret;
  304. }
  305. //CRC对照表
  306. const uint8_t SPI_TableCRC[256] =
  307. {
  308. //The ?°crc?± of the position [1] (result from operation [crc ^*(message+Byteidx)])
  309. //is 0x00 -> 0x00 XOR 0x11D = 0x00 (1 byte).
  310. 0x00,
  311. //The ?°crc?± of the position [2] is 0x1D -> 0x01 XOR 0x11D = 0x1D (1 byte).
  312. 0x1D,
  313. //The ?°crc?± of the position [3] is 0x3A -> 0x02 XOR 0x11D = 0x3A (1 byte).
  314. 0x3A,
  315. //For all the rest of the cases.
  316. 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 0xCD,
  317. 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B,
  318. 0x76, 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B,
  319. 0x06, 0x21, 0x3C, 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98,
  320. 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB,
  321. 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90,
  322. 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, 0x94, 0x89, 0xAE, 0xB3, 0xE0,
  323. 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63,
  324. 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26,
  325. 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80,
  326. 0x9D, 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77,
  327. 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73,
  328. 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84,
  329. 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B,
  330. 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C,
  331. 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88,
  332. 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F,
  333. 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFe,
  334. //The ?°crc?± of the position [255] is 0xD9 -> 0xFE XOR 0x11D = 0xD9 (1 byte).
  335. 0xD9,
  336. //The ?°crc?± of the position [256] is 0xC4 -> 0xFF XOR 0x11D = 0xC4 (1 byte).
  337. 0xC4
  338. };
  339. //配置
  340. uint8_t SPI_CRC8(uint8_t *message, uint8_t Bytelength )
  341. {
  342. //?°crc?± defined as the 8-bits that will be generated through the message till the
  343. //final crc is generated. In the example above this are the blue lines out of the
  344. //XOR operation.
  345. uint8_t crc;
  346. //?°Byteidx?± is a counter to compare the bytes used for the CRC calculation and
  347. //?°Bytelength?±.
  348. uint8_t Byteidx;
  349. //Initially the CRC remainder has to be set with the original seed (0xFF for the TLE5012B).
  350. crc = 0xFF;
  351. //For all the bytes of the message.
  352. for(Byteidx=0; Byteidx<Bytelength; Byteidx++)
  353. {
  354. //?°crc?± is the value in the look-up table TableCRC[x] at the position ?°x?±.
  355. //The position ?°x?± is determined as the XOR operation between the previous ?°crc?± and
  356. //the next byte of the ?°message?±.
  357. //?°^?± is the XOR operator.
  358. crc = SPI_TableCRC[crc ^ *(message+Byteidx)];
  359. }
  360. //Return the inverted ?°crc?± remainder(?°~?± is the invertion operator). An alternative
  361. //to the ?°~?± operator would be a XOR operation between ?°crc?± and a 0xFF polynomial.
  362. return(~crc);
  363. }