#include "bexus_mag.h" // Defines //////////////////////////////////////////////////////////////// #define LIS3MDL_SA1_HIGH_ADDRESS 0x1e<<1 #define LIS3MDL_SA1_LOW_ADDRESS 0x1c<<1 #define TEST_REG_ERROR -1 #define LIS3MDL_WHO_ID 0x3D uint8_t address = LIS3MDL_SA1_HIGH_ADDRESS; //double gauss_scale=1711;//für +-16 gauss uint8_t xlm, xhm, ylm, yhm, zlm, zhm, tlm, thm; uint8_t status_reg; uint8_t reg_zor=0x02, reg_yor=0x04, reg_xor=0x08, reg_zda=0x20, reg_yda=0x40, reg_xda=0x80; int16_t reg_cal[3][2]={{0,0},{0,0},{0,0}}; // [x,y,z] [min,max] int16_t reg_cal_offset[2];//offset for [min,max] void Mag_cal(void) { //Mag_Init(); uint8_t temp_buff[6]; uint8_t val = 0x06; uint8_t outxl[2] = {OUT_X_L | 0x80,val}; for(int i=0;i<500;i++){ if(HAL_OK == HAL_I2C_Master_Transmit(&hi2c1,address,outxl,2,10)) HAL_I2C_Master_Receive(&hi2c1,address,temp_buff,sizeof(temp_buff),10); xlm = temp_buff[0]; xhm = temp_buff[1]; ylm = temp_buff[2]; yhm = temp_buff[3]; zlm = temp_buff[4]; zhm = temp_buff[5]; // combine high and low bytes int16_t buff_cal[3] = {(int16_t)((xhm << 8) | xlm) , (int16_t)((yhm << 8) | ylm) , (int16_t)((zhm << 8) | zlm)}; for(int i=0;i<3;i++) if(buff_cal[i] < reg_cal[i][0]) reg_cal[i][0] = buff_cal[i]; for(int i=0;i<3;i++) if(buff_cal[i] > reg_cal[i][1]) reg_cal[i][1] = buff_cal[i]; HAL_Delay(10); } reg_cal_offset[0]=(reg_cal[0][0] + reg_cal[1][0] + reg_cal[2][0])/3.; reg_cal_offset[1]=(reg_cal[0][1] + reg_cal[1][1] + reg_cal[2][1])/3.; } void Mag_Init(void) { // ultra-high-performance mode for X and Y, 155 Hz FAST_ODR //writeReg(CTRL_REG1, 0xE2); writeReg(CTRL_REG1, 0xFC); // +/- gauss full scale writeReg(CTRL_REG2, 0x60); //+-16 //writeReg(CTRL_REG2, 0x20);//+-8 // continuous-conversion mode writeReg(CTRL_REG3, 0x00); // ultra-high-performance mode for Z writeReg(CTRL_REG4, 0x0C); } // Writes a mag register void writeReg(uint8_t reg, uint8_t value){ uint8_t temp_mag[2]={reg,value}; HAL_I2C_Master_Transmit(&hi2c1,address,temp_mag,2,50); } // Reads a mag register uint8_t readReg(uint8_t reg){ uint8_t value; uint8_t val [2]= {reg,0x01}; if(HAL_OK == HAL_I2C_Master_Transmit(&hi2c1,address,val,1,10)) HAL_I2C_Master_Receive(&hi2c1,address,&value,1,35); return value; } struct Dataset *data_mag = &Dataset_Master[0]; struct vector_Uint data_mag_save; // Reads the 3 mag channels int Mag_Read() { uint8_t temp_buff[9]; uint8_t val = 0x09; uint8_t outxl[2] = {STATUS_REG | 0x80,val}; if(HAL_OK == HAL_I2C_Master_Transmit(&hi2c1,address,outxl,2,50)) if(HAL_OK != HAL_I2C_Master_Receive(&hi2c1,address,temp_buff,sizeof(temp_buff),50)) return HAL_ERROR; status_reg = temp_buff[0]; xlm = temp_buff[1]; xhm = temp_buff[2]; ylm = temp_buff[3]; yhm = temp_buff[4]; zlm = temp_buff[5]; zhm = temp_buff[6]; tlm = temp_buff[7]; thm = temp_buff[8]; // combine high and low bytes data_mag->mag_raw.x = (int16_t)((xhm << 8) | xlm); data_mag->mag_raw.y = (int16_t)((yhm << 8) | ylm); data_mag->mag_raw.z = (int16_t)((zhm << 8) | zlm); data_mag->temperature_mag_raw = (int32_t)((thm << 8) | tlm); data_mag->temperature_mag_raw = data_mag->temperature_mag_raw - (data_mag->temperature_mag_raw & 0xFF00); //check for new/overrun data and calculate dataset // if(((reg_xor & status_reg) != reg_xor)&&((reg_xda & status_reg) == reg_xda)) // data_mag->mag.x = (double)data_mag->mag_raw.x; // else // data_mag->mag.x = data_mag_prev->mag.x; // // // if(((reg_yor & status_reg) != reg_yor)&&((reg_yda & status_reg) == reg_yda)) // data_mag->mag.y=(double)(data_mag->mag_raw.y); // else // data_mag->mag.y = data_mag_prev->mag.y; // // // if(((reg_zor & status_reg) != reg_zor)&&((reg_zda & status_reg) == reg_zda)) // data_mag->mag.z=(double)(data_mag->mag_raw.z); // else // data_mag->mag.z = data_mag_prev->mag.z; if(abs(data_mag->mag_raw.x - data_mag_save.x) < 20000) { data_mag_save.x = data_mag->mag_raw.x; } if(abs(data_mag->mag_raw.y - data_mag_save.y) < 20000) { data_mag_save.y = data_mag->mag_raw.y; } if(abs(data_mag->mag_raw.z - data_mag_save.z) < 20000) { data_mag_save.z = data_mag->mag_raw.z; } #ifdef BOARD_HAS_ETHERNET data_mag->mag.x = - data_mag_save.y + 0.; data_mag->mag.y = + data_mag_save.x + 0.; data_mag->mag.z = + data_mag_save.z + 0.; #else data_mag->mag.x = - data_mag_save.y + 0.; data_mag->mag.y = + data_mag_save.x + 0.; data_mag->mag.z = + data_mag_save.z + 0.; #endif double temp_temp=(double)((data_mag->temperature_mag_raw)/256.)+25; if(temp_temp<100){//checking for false data, since there is no crc for the temperature register data_mag->temperature_mag = temp_temp; } /* if(data_mag->mag_raw.x >= 32768) data_mag->mag.x=(double)((data_mag->mag_raw.x*1.-32768)/32768*16); else data_mag->mag.x=0-(double)((data_mag->mag_raw.x*1.)/32768*16); */ return HAL_OK; } double vector_dot(struct vector *a, struct vector *b) { return (a->x * b->x) + (a->y * b->y) + (a->z * b->z); } void vector_normalize(struct vector *a) { double mag_d = sqrt(vector_dot(a, a)); a->x /= mag_d; a->y /= mag_d; a->z /= mag_d; } // Private Methods ////////////////////////////////////////////////////////////// uint8_t testReg(uint8_t address, uint8_t reg){ uint8_t val[2] = {reg,0x01}; uint8_t erg; if(HAL_OK ==HAL_I2C_Master_Transmit(&hi2c1,address,val,2,50)) HAL_I2C_Master_Receive(&hi2c1,address,&erg,1,50); return erg; }