MT6816_ATY.c.bak 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * @file MT6816_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2026 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief functions of MT6816 magnetic encoder for C platform
  20. *
  21. * @note SPI_POLARITY_HIGH + SPI_PHASE_1EDGE = CPOL=1, CPHA=0 = SPI Mode 2
  22. *
  23. * @version
  24. * - 1_01_251222 > ATY
  25. * -# Preliminary version, first Release
  26. ********************************************************************************
  27. */
  28. #ifndef __MT6816_ATY_C
  29. #define __MT6816_ATY_C
  30. #include "MT6816_ATY.h"
  31. #define MT6816_ATY_TAG "\r\n[MT6816_ATY] "
  32. /******************************* For user *************************************/
  33. /******************************************************************************/
  34. uint8_t wrData[6] = {0};
  35. /**
  36. * @brief Parity check
  37. *
  38. * @param dev Device structure pointer
  39. * @param data Data
  40. * @return uint8_t Execution result
  41. */
  42. uint8_t MT6816_ParityCheck(struct MT6816_ATY_Dev* dev, uint16_t data){
  43. uint8_t parityCheck = 0;
  44. if(data == 0) data = dev->angleValue;
  45. dev->error &= ~(uint8_t)MT6816_PARITY_CHECK_MASK;
  46. for (int i = 0; i < 15; i++) {
  47. data >>= 1;
  48. if (data & 0x01) {
  49. parityCheck ^= 1;
  50. }
  51. }
  52. // Check if parity bit matches (parity bit is bit 7 of angle_lsb)
  53. if ((dev->angleValue & 0x01) != parityCheck) {
  54. dev->error |= MT6816_PARITY_CHECK_MASK;
  55. printf_ATY_D("%sParity check failed", MT6816_ATY_TAG);
  56. }
  57. return dev->error;
  58. }
  59. /**
  60. * @brief MT6816_ErrorCheck
  61. *
  62. * @param dev Device structure pointer
  63. * @param data Data
  64. * @return uint8_t Execution result
  65. */
  66. uint8_t MT6816_ErrorCheck(struct MT6816_ATY_Dev* dev, uint8_t* data){
  67. dev->error = 0;
  68. MT6816_ParityCheck(dev, (data[0] << 8) | data[1]);
  69. if(data[1] & MT6816_NO_MAG_WARNING_MASK){
  70. dev->error |= MT6816_NO_MAG_WARNING_MASK;
  71. printf_ATY_D("%sNo magnetic field warning", MT6816_ATY_TAG);
  72. }
  73. if(data[2] & MT6816_OVER_SPEED_MASK){
  74. dev->error |= MT6816_OVER_SPEED_MASK;
  75. printf_ATY_D("%sOver speed warning", MT6816_ATY_TAG);
  76. }
  77. return dev->error;
  78. }
  79. /**
  80. * @brief Read angle value from MT6816 for only angle value
  81. *
  82. * @param dev Device structure pointer
  83. * @return uint8_t Execution result
  84. */
  85. uint8_t MT6816_ReadAngleBase(struct MT6816_ATY_Dev* dev){
  86. __ATY_LOCK(dev);
  87. // Reading MSB (ANGLE_MSB register)
  88. wrData[0] = MT6816_REG_ANGLE_13_6 | 0x80;
  89. dev->nssSet(__ATY_HL_L);
  90. dev->spiProcess(wrData, 1, __ATY_RW_W);
  91. dev->spiProcess(wrData, 1, __ATY_RW_R);
  92. dev->nssSet(__ATY_HL_H);
  93. wrData[3] = wrData[0];
  94. dev->angleValue = ((uint16_t)wrData[0] << 8);
  95. // Reading LSB (ANGLE_LSB register)
  96. wrData[0] = MT6816_REG_ANGLE_5_0 | 0x80;
  97. dev->nssSet(__ATY_HL_L);
  98. dev->spiProcess(wrData, 1, __ATY_RW_W);
  99. dev->spiProcess(wrData, 1, __ATY_RW_R);
  100. dev->nssSet(__ATY_HL_H);
  101. wrData[4] = wrData[0];
  102. dev->angleValue |= (wrData[0]);
  103. MT6816_ParityCheck(dev, 0);
  104. // dev->angleValue >>= 2;
  105. MT6816_CalculateAngleReal(dev, 0);
  106. __ATY_UNLOCK(dev);
  107. return 0;
  108. }
  109. /**
  110. * @brief Read angle value from MT6816 for all 3 regs
  111. *
  112. * @param dev Device structure pointer
  113. * @return uint8_t Execution result
  114. */
  115. uint8_t MT6816_ReadAngleFull(struct MT6816_ATY_Dev* dev){
  116. __ATY_LOCK(dev);
  117. wrData[0] = MT6816_REG_ANGLE_13_6 | 0x80;
  118. dev->nssSet(__ATY_HL_L);
  119. dev->spiProcess(wrData, 1, __ATY_RW_W);
  120. dev->spiProcess(wrData, 3, __ATY_RW_R);
  121. dev->nssSet(__ATY_HL_H);
  122. // Combine MSB and LSB to form 14-bit angle value
  123. dev->angleValue = ((uint16_t)wrData[0] << 8 | wrData[1]);
  124. MT6816_ErrorCheck(dev, wrData);
  125. // dev->angleValue >>= 2;
  126. MT6816_CalculateAngleReal(dev, 0);
  127. __ATY_UNLOCK(dev);
  128. return 0;
  129. }
  130. /**
  131. * @brief Set zero point
  132. *
  133. * @param dev Device structure pointer
  134. * @return uint8_t Zero point value
  135. */
  136. uint16_t MT6816_SetZeroPoint(struct MT6816_ATY_Dev* dev){
  137. MT6816_ReadAngleFull(dev);
  138. dev->zeroPoint = dev->angleValue >> 2;
  139. return dev->zeroPoint;
  140. }
  141. /**
  142. * @brief Calculate angle in degrees from raw value
  143. *
  144. * @param dev Device structure pointer
  145. * @param angle Raw angle value, if 0, use internal angle value
  146. * @return float Angle in degrees
  147. */
  148. float MT6816_CalculateAngle(struct MT6816_ATY_Dev* dev, uint16_t angle){
  149. if(angle == 0) angle = dev->angleValue >> 2;
  150. dev->angle = (float)angle * 360.0 / 16384.0;
  151. dev->angle = 360.0 - dev->angle;
  152. return dev->angle;
  153. }
  154. /**
  155. * @brief Calculate angle in degrees from raw value and remove zero diff
  156. *
  157. * @param dev Device structure pointer
  158. * @param angle Raw angle value, if 0, use internal angle value
  159. * @return float Angle in degrees
  160. */
  161. float MT6816_CalculateAngleReal(struct MT6816_ATY_Dev* dev, uint16_t angle){
  162. if(angle == 0) angle = dev->angleValue >> 2;
  163. if(angle < dev->zeroPoint) angle += 16384;
  164. dev->angle = (float)(angle - dev->zeroPoint) * 360.0 / 16384.0;
  165. dev->angle = 360.0 - dev->angle;
  166. return dev->angle;
  167. }
  168. #endif /* __MT6816_ATY_C */
  169. /************************************ etc *************************************/
  170. /* init */
  171. // MT6816 --------------------------------------------------------------------
  172. // #include "MT6816_ATY.h"
  173. // void MT6816_1_NSS_SET(uint8_t level){
  174. // if(level == __ATY_HL_L)
  175. // HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_RESET);
  176. // else if(level == __ATY_HL_H)
  177. // HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);
  178. // }
  179. // uint8_t MT6816_1_SPI(uint8_t* data_t, uint16_t len, uint8_t rw){
  180. // if(rw == __ATY_RW_R){
  181. // return HAL_SPI_Receive(&hspi1, (uint8_t*)data_t, len, 1000);
  182. // }
  183. // else{
  184. // return HAL_SPI_Transmit(&hspi1, (uint8_t*)data_t, len, 1000);
  185. // }
  186. // }
  187. // struct MT6816_ATY_Dev MT6816_ATY_Dev_1 = {
  188. // .nssSet = MT6816_1_NSS_SET,
  189. // .spiProcess = MT6816_1_SPI,
  190. //
  191. // .angleValue = 0,
  192. // .angle = 0,
  193. // .error = 0,
  194. //
  195. // .lock = __ATY_UNLOCKED
  196. // };
  197. /* use */
  198. // MT6816_ReadAngleFull(&MT6816_ATY_Dev_1);
  199. // printf_ATY("\r\nAngle: 0x%04X, Degrees: %.2f",
  200. // MT6816_ATY_Dev_1.angleValue,
  201. // MT6816_ATY_Dev_1.angle);
  202. /******************************************************************************/
  203. /******************************** End Of File *********************************/