bexus_mag.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "bexus_mag.h"
  2. // Defines ////////////////////////////////////////////////////////////////
  3. #define LIS3MDL_SA1_HIGH_ADDRESS 0x1e<<1
  4. #define LIS3MDL_SA1_LOW_ADDRESS 0x1c<<1
  5. #define TEST_REG_ERROR -1
  6. #define LIS3MDL_WHO_ID 0x3D
  7. uint8_t address = LIS3MDL_SA1_HIGH_ADDRESS;
  8. //double gauss_scale=1711;//für +-16 gauss
  9. uint8_t xlm, xhm, ylm, yhm, zlm, zhm, tlm, thm;
  10. uint8_t status_reg;
  11. uint8_t reg_zor=0x02, reg_yor=0x04, reg_xor=0x08, reg_zda=0x20, reg_yda=0x40, reg_xda=0x80;
  12. int16_t reg_cal[3][2]={{0,0},{0,0},{0,0}}; // [x,y,z] [min,max]
  13. int16_t reg_cal_offset[2];//offset for [min,max]
  14. void Mag_cal(void) {
  15. //Mag_Init();
  16. uint8_t temp_buff[6];
  17. uint8_t val = 0x06;
  18. uint8_t outxl[2] = {OUT_X_L | 0x80,val};
  19. for(int i=0;i<500;i++){
  20. if(HAL_OK == HAL_I2C_Master_Transmit(&hi2c1,address,outxl,2,10))
  21. HAL_I2C_Master_Receive(&hi2c1,address,temp_buff,sizeof(temp_buff),10);
  22. xlm = temp_buff[0];
  23. xhm = temp_buff[1];
  24. ylm = temp_buff[2];
  25. yhm = temp_buff[3];
  26. zlm = temp_buff[4];
  27. zhm = temp_buff[5];
  28. // combine high and low bytes
  29. int16_t buff_cal[3] = {(int16_t)((xhm << 8) | xlm) , (int16_t)((yhm << 8) | ylm) , (int16_t)((zhm << 8) | zlm)};
  30. for(int i=0;i<3;i++) if(buff_cal[i] < reg_cal[i][0]) reg_cal[i][0] = buff_cal[i];
  31. for(int i=0;i<3;i++) if(buff_cal[i] > reg_cal[i][1]) reg_cal[i][1] = buff_cal[i];
  32. HAL_Delay(10);
  33. }
  34. reg_cal_offset[0]=(reg_cal[0][0] + reg_cal[1][0] + reg_cal[2][0])/3.;
  35. reg_cal_offset[1]=(reg_cal[0][1] + reg_cal[1][1] + reg_cal[2][1])/3.;
  36. }
  37. void Mag_Init(void) {
  38. // ultra-high-performance mode for X and Y, 155 Hz FAST_ODR
  39. //writeReg(CTRL_REG1, 0xE2);
  40. writeReg(CTRL_REG1, 0xFC);
  41. // +/- gauss full scale
  42. writeReg(CTRL_REG2, 0x60); //+-16
  43. //writeReg(CTRL_REG2, 0x20);//+-8
  44. // continuous-conversion mode
  45. writeReg(CTRL_REG3, 0x00);
  46. // ultra-high-performance mode for Z
  47. writeReg(CTRL_REG4, 0x0C);
  48. }
  49. // Writes a mag register
  50. void writeReg(uint8_t reg, uint8_t value){
  51. uint8_t temp_mag[2]={reg,value};
  52. HAL_I2C_Master_Transmit(&hi2c1,address,temp_mag,2,50);
  53. }
  54. // Reads a mag register
  55. uint8_t readReg(uint8_t reg){
  56. uint8_t value;
  57. uint8_t val [2]= {reg,0x01};
  58. if(HAL_OK == HAL_I2C_Master_Transmit(&hi2c1,address,val,1,10))
  59. HAL_I2C_Master_Receive(&hi2c1,address,&value,1,35);
  60. return value;
  61. }
  62. struct Dataset *data_mag = &Dataset_Master[0];
  63. struct vector_Uint data_mag_save;
  64. // Reads the 3 mag channels
  65. int Mag_Read() {
  66. uint8_t temp_buff[9];
  67. uint8_t val = 0x09;
  68. uint8_t outxl[2] = {STATUS_REG | 0x80,val};
  69. if(HAL_OK == HAL_I2C_Master_Transmit(&hi2c1,address,outxl,2,50))
  70. if(HAL_OK != HAL_I2C_Master_Receive(&hi2c1,address,temp_buff,sizeof(temp_buff),50))
  71. return HAL_ERROR;
  72. status_reg = temp_buff[0];
  73. xlm = temp_buff[1];
  74. xhm = temp_buff[2];
  75. ylm = temp_buff[3];
  76. yhm = temp_buff[4];
  77. zlm = temp_buff[5];
  78. zhm = temp_buff[6];
  79. tlm = temp_buff[7];
  80. thm = temp_buff[8];
  81. // combine high and low bytes
  82. data_mag->mag_raw.x = (int16_t)((xhm << 8) | xlm);
  83. data_mag->mag_raw.y = (int16_t)((yhm << 8) | ylm);
  84. data_mag->mag_raw.z = (int16_t)((zhm << 8) | zlm);
  85. data_mag->temperature_mag_raw = (int32_t)((thm << 8) | tlm);
  86. data_mag->temperature_mag_raw = data_mag->temperature_mag_raw - (data_mag->temperature_mag_raw & 0xFF00);
  87. //check for new/overrun data and calculate dataset
  88. // if(((reg_xor & status_reg) != reg_xor)&&((reg_xda & status_reg) == reg_xda))
  89. // data_mag->mag.x = (double)data_mag->mag_raw.x;
  90. // else
  91. // data_mag->mag.x = data_mag_prev->mag.x;
  92. //
  93. //
  94. // if(((reg_yor & status_reg) != reg_yor)&&((reg_yda & status_reg) == reg_yda))
  95. // data_mag->mag.y=(double)(data_mag->mag_raw.y);
  96. // else
  97. // data_mag->mag.y = data_mag_prev->mag.y;
  98. //
  99. //
  100. // if(((reg_zor & status_reg) != reg_zor)&&((reg_zda & status_reg) == reg_zda))
  101. // data_mag->mag.z=(double)(data_mag->mag_raw.z);
  102. // else
  103. // data_mag->mag.z = data_mag_prev->mag.z;
  104. if(abs(data_mag->mag_raw.x - data_mag_save.x) < 20000) {
  105. data_mag_save.x = data_mag->mag_raw.x;
  106. }
  107. if(abs(data_mag->mag_raw.y - data_mag_save.y) < 20000) {
  108. data_mag_save.y = data_mag->mag_raw.y;
  109. }
  110. if(abs(data_mag->mag_raw.z - data_mag_save.z) < 20000) {
  111. data_mag_save.z = data_mag->mag_raw.z;
  112. }
  113. #ifdef BOARD_HAS_ETHERNET
  114. data_mag->mag.x = - data_mag_save.y + 0.;
  115. data_mag->mag.y = + data_mag_save.x + 0.;
  116. data_mag->mag.z = + data_mag_save.z + 0.;
  117. #else
  118. data_mag->mag.x = - data_mag_save.y + 0.;
  119. data_mag->mag.y = + data_mag_save.x + 0.;
  120. data_mag->mag.z = + data_mag_save.z + 0.;
  121. #endif
  122. double temp_temp=(double)((data_mag->temperature_mag_raw)/256.)+25;
  123. if(temp_temp<100){//checking for false data, since there is no crc for the temperature register
  124. data_mag->temperature_mag = temp_temp;
  125. }
  126. /*
  127. if(data_mag->mag_raw.x >= 32768)
  128. data_mag->mag.x=(double)((data_mag->mag_raw.x*1.-32768)/32768*16);
  129. else
  130. data_mag->mag.x=0-(double)((data_mag->mag_raw.x*1.)/32768*16);
  131. */
  132. return HAL_OK;
  133. }
  134. double vector_dot(struct vector *a, struct vector *b) {
  135. return (a->x * b->x) + (a->y * b->y) + (a->z * b->z);
  136. }
  137. void vector_normalize(struct vector *a)
  138. {
  139. double mag_d = sqrt(vector_dot(a, a));
  140. a->x /= mag_d;
  141. a->y /= mag_d;
  142. a->z /= mag_d;
  143. }
  144. // Private Methods //////////////////////////////////////////////////////////////
  145. uint8_t testReg(uint8_t address, uint8_t reg){
  146. uint8_t val[2] = {reg,0x01};
  147. uint8_t erg;
  148. if(HAL_OK ==HAL_I2C_Master_Transmit(&hi2c1,address,val,2,50))
  149. HAL_I2C_Master_Receive(&hi2c1,address,&erg,1,50);
  150. return erg;
  151. }