bool mpu6050GyroDetect(const mpu6050Config_t *configToUse, gyro_t *gyro, uint16_t lpf) { mpu6050Config = configToUse; if (!mpu6050Detect()) { return false; } gyro->init = mpu6050GyroInit; gyro->read = mpu6050GyroRead; gyro->intStatus = checkMPU6050Interrupt; // 16.4 dps/lsb scalefactor gyro->scale = 1.0f / 16.4f; if (lpf == 256) mpuLowPassFilter = INV_FILTER_256HZ_NOLPF2; else if (lpf >= 188) mpuLowPassFilter = INV_FILTER_188HZ; else if (lpf >= 98) mpuLowPassFilter = INV_FILTER_98HZ; else if (lpf >= 42) mpuLowPassFilter = INV_FILTER_42HZ; else if (lpf >= 20) mpuLowPassFilter = INV_FILTER_20HZ; else if (lpf >= 10) mpuLowPassFilter = INV_FILTER_10HZ; else if (lpf > 0) mpuLowPassFilter = INV_FILTER_5HZ; else mpuLowPassFilter = INV_FILTER_256HZ_NOLPF2; return true; }
void sensorsInit(void) { zeroSensorAccumulators(); // TODO allow user to select hardware if there are multiple choices if(mpu6050Detect(&gyro, &accel, cfg.mpu6050Scale)) { sensorsSet(SENSOR_ACC); } else if(!mpu3050Detect(&gyro)) { failureMode(3); } if(adxl345Detect(&accel)) { sensorsSet(SENSOR_ACC); } // At the moment we will do this after mpu6050 and overrride mpu6050 accel if detected if(mma8452Detect(&accel)) { sensorsSet(SENSOR_ACC); } gyro.init(); if(sensorsGet(SENSOR_ACC)) accel.init(); if(hmc5883Detect(&mag)) { mag.init(); sensorsSet(SENSOR_MAG); } #ifdef SONAR if(feature(FEATURE_PPM);) {
bool mpu6050AccDetect(const mpu6050Config_t *configToUse, acc_t *acc) { uint8_t readBuffer[6]; uint8_t revision; uint8_t productId; mpu6050Config = configToUse; if (!mpu6050Detect()) { return false; } // There is a map of revision contained in the android source tree which is quite comprehensive and may help to understand this code // See https://android.googlesource.com/kernel/msm.git/+/eaf36994a3992b8f918c18e4f7411e8b2320a35f/drivers/misc/mpu6050/mldl_cfg.c // determine product ID and accel revision i2cRead(MPU6050_ADDRESS, MPU_RA_XA_OFFS_H, 6, readBuffer); revision = ((readBuffer[5] & 0x01) << 2) | ((readBuffer[3] & 0x01) << 1) | (readBuffer[1] & 0x01); if (revision) { /* Congrats, these parts are better. */ if (revision == 1) { mpuAccelTrim = MPU_6050_HALF_RESOLUTION; } else if (revision == 2) { mpuAccelTrim = MPU_6050_FULL_RESOLUTION; } else { failureMode(FAILURE_ACC_INCOMPATIBLE); } } else { i2cRead(MPU6050_ADDRESS, MPU_RA_PRODUCT_ID, 1, &productId); revision = productId & 0x0F; if (!revision) { failureMode(FAILURE_ACC_INCOMPATIBLE); } else if (revision == 4) { mpuAccelTrim = MPU_6050_HALF_RESOLUTION; } else { mpuAccelTrim = MPU_6050_FULL_RESOLUTION; } } acc->init = mpu6050AccInit; acc->read = mpu6050AccRead; acc->revisionCode = (mpuAccelTrim == MPU_6050_HALF_RESOLUTION ? 'o' : 'n'); // es/non-es variance between MPU6050 sensors, half of the naze boards are mpu6000ES. return true; }
bool mpu6050GyroDetect(gyro_t *gyro, uint16_t lpf) { if (!mpu6050Detect()) { return false; } gyro->init = mpu6050GyroInit; gyro->read = mpu6050GyroRead; // 16.4 dps/lsb scalefactor gyro->scale = 1.0f / 16.4f; // default lpf is 42Hz switch (lpf) { case 256: mpuLowPassFilter = MPU6050_LPF_256HZ; break; case 188: mpuLowPassFilter = MPU6050_LPF_188HZ; break; case 98: mpuLowPassFilter = MPU6050_LPF_98HZ; break; default: case 42: mpuLowPassFilter = MPU6050_LPF_42HZ; break; case 20: mpuLowPassFilter = MPU6050_LPF_20HZ; break; case 10: mpuLowPassFilter = MPU6050_LPF_10HZ; break; case 5: mpuLowPassFilter = MPU6050_LPF_5HZ; break; } return true; }
bool sensorsAutodetect(void) { int16_t deg, min; drv_adxl345_config_t acc_params; bool haveMpu6k = false; // Autodetect gyro hardware. We have MPU3050 or MPU6050. if (mpu6050Detect(&acc, &gyro, mcfg.gyro_lpf, &core.mpu6050_scale)) { // this filled up acc.* struct with init values haveMpu6k = true; } else if (l3g4200dDetect(&gyro, mcfg.gyro_lpf)) { // well, we found our gyro ; } else if (!mpu3050Detect(&gyro, mcfg.gyro_lpf)) { // if this fails, we get a beep + blink pattern. we're doomed, no gyro or i2c error. return false; } // Accelerometer. F**k it. Let user break shit. retry: switch (mcfg.acc_hardware) { case ACC_NONE: // disable ACC sensorsClear(SENSOR_ACC); break; case ACC_DEFAULT: // autodetect case ACC_ADXL345: // ADXL345 acc_params.useFifo = false; acc_params.dataRate = 800; // unused currently if (adxl345Detect(&acc_params, &acc)) accHardware = ACC_ADXL345; if (mcfg.acc_hardware == ACC_ADXL345) break; ; // fallthrough case ACC_MPU6050: // MPU6050 if (haveMpu6k) { mpu6050Detect(&acc, &gyro, mcfg.gyro_lpf, &core.mpu6050_scale); // yes, i'm rerunning it again. re-fill acc struct accHardware = ACC_MPU6050; if (mcfg.acc_hardware == ACC_MPU6050) break; } ; // fallthrough #ifndef OLIMEXINO case ACC_MMA8452: // MMA8452 if (mma8452Detect(&acc)) { accHardware = ACC_MMA8452; if (mcfg.acc_hardware == ACC_MMA8452) break; } ; // fallthrough case ACC_BMA280: // BMA280 if (bma280Detect(&acc)) { accHardware = ACC_BMA280; if (mcfg.acc_hardware == ACC_BMA280) break; } #endif } // Found anything? Check if user f****d up or ACC is really missing. if (accHardware == ACC_DEFAULT) { if (mcfg.acc_hardware > ACC_DEFAULT) { // Nothing was found and we have a forced sensor type. Stupid user probably chose a sensor that isn't present. mcfg.acc_hardware = ACC_DEFAULT; goto retry; } else { // We're really screwed sensorsClear(SENSOR_ACC); } } #ifdef BARO // Detect what pressure sensors are available. baro->update() is set to sensor-specific update function if (!bmp085Detect(&baro)) { // ms5611 disables BMP085, and tries to initialize + check PROM crc. // moved 5611 init here because there have been some reports that calibration data in BMP180 // has been "passing" ms5611 PROM crc check if (!ms5611Detect(&baro)) { // if both failed, we don't have anything sensorsClear(SENSOR_BARO); } } #endif // Now time to init things, acc first if (sensors(SENSOR_ACC)) acc.init(mcfg.acc_align); // this is safe because either mpu6050 or mpu3050 or lg3d20 sets it, and in case of fail, we never get here. gyro.init(mcfg.gyro_align); #ifdef MAG if (!hmc5883lDetect(mcfg.mag_align)) sensorsClear(SENSOR_MAG); #endif // calculate magnetic declination deg = cfg.mag_declination / 100; min = cfg.mag_declination % 100; if (sensors(SENSOR_MAG)) magneticDeclination = (deg + ((float)min * (1.0f / 60.0f))) * 10; // heading is in 0.1deg units else magneticDeclination = 0.0f; return true; }
void SensorDetectAndINI(void) // "enabledSensors" is "0" in config.c so all sensors disabled per default { int16_t deg, min; uint8_t sig = 0; bool ack = false; bool haveMpu6k = false; GyroScale16 = (16.0f / 16.4f) * RADX; // GYRO part. RAD per SECOND, take into account that gyrodata are div by X if (mpu6050Detect(&acc, &gyro)) // Autodetect gyro hardware. We have MPU3050 or MPU6050. { haveMpu6k = true; // this filled up acc.* struct with init values } else if (l3g4200dDetect(&gyro)) { havel3g4200d = true; GyroScale16 = (16.0f / 14.2857f) * RADX; // GYRO part. RAD per SECOND, take into account that gyrodata are div by X } else if (!mpu3050Detect(&gyro)) { failureMode(3); // if this fails, we get a beep + blink pattern. we're doomed, no gyro or i2c error. } sensorsSet(SENSOR_ACC); // ACC part. Will be cleared if not available retry: switch (cfg.acc_hdw) { case 0: // autodetect case 1: // ADXL345 if (adxl345Detect(&acc)) accHardware = ACC_ADXL345; if (cfg.acc_hdw == ACC_ADXL345) break; case 2: // MPU6050 if (haveMpu6k) { mpu6050Detect(&acc, &gyro); // yes, i'm rerunning it again. re-fill acc struct accHardware = ACC_MPU6050; if (cfg.acc_hdw == ACC_MPU6050) break; } case 3: // MMA8452 if (mma8452Detect(&acc)) { accHardware = ACC_MMA8452; if (cfg.acc_hdw == ACC_MMA8452) break; } } if (accHardware == ACC_DEFAULT) // Found anything? Check if user f****d up or ACC is really missing. { if (cfg.acc_hdw > ACC_DEFAULT) { cfg.acc_hdw = ACC_DEFAULT; // Nothing was found and we have a forced sensor type. User probably chose a sensor that isn't present. goto retry; } else sensorsClear(SENSOR_ACC); // We're really screwed } if (sensors(SENSOR_ACC)) acc.init(); if (haveMpu6k && accHardware == ACC_MPU6050) MpuSpecial = true; else MpuSpecial = false; if (feature(FEATURE_PASS)) return; // Stop here we need just ACC for Vibrationmonitoring if present if (feature(FEATURE_GPS) && !SerialRCRX) gpsInit(cfg.gps_baudrate);// SerialRX and GPS can not coexist. gyro.init(); // this is safe because either mpu6050 or mpu3050 or lg3d20 sets it, and in case of fail, we never get here. if (havel3g4200d) l3g4200dConfig(); else if (!haveMpu6k) mpu3050Config(); Gyro_Calibrate(); // Do Gyrocalibration here (is blocking), provides nice Warmuptime for the following rest! #ifdef MAG if (hmc5883lDetect()) { sensorsSet(SENSOR_MAG); hmc5883lInit(magCal); // Crashpilot: Calculate Gains / Scale deg = cfg.mag_dec / 100; // calculate magnetic declination min = cfg.mag_dec % 100; magneticDeclination = ((float)deg + ((float)min / 60.0f));// heading is in decimaldeg units NO 0.1 deg shit here } #endif #ifdef BARO // No delay necessary since Gyrocal blocked a lot already ack = i2cRead(0x77, 0x77, 1, &sig); // Check Baroadr.(MS & BMP) BMP will say hello here, MS not if ( ack) ack = bmp085Detect(&baro); // Are we really dealing with BMP? if (!ack) ack = ms5611Detect(&baro); // No, Check for MS Baro if (ack) sensorsSet(SENSOR_BARO); if(cfg.esc_nfly) ESCnoFlyThrottle = constrain_int(cfg.esc_nfly, cfg.esc_min, cfg.esc_max); // Set the ESC PWM signal threshold for not flyable RPM else ESCnoFlyThrottle = cfg.esc_min + (((cfg.esc_max - cfg.esc_min) * 5) / 100); // If not configured, take 5% above esc_min #endif #ifdef SONAR if (feature(FEATURE_SONAR)) Sonar_init(); // Initialize Sonars here depending on Rc configuration. SonarLandWanted = cfg.snr_land; // Variable may be overwritten by failsave #endif MainDptCut = RCconstPI / (float)cfg.maincuthz; // Initialize Cut off frequencies for mainpid D }
// AfroFlight32 i2c sensors void nazeDriversInit( uint8_t accHardware ) { // int16_t deg, min; drv_adxl345_config_t acc_params; bool haveMpu6k = false; uint16_t gyro_lpf = 28; uint8_t gyro_scale = 1; //Assume we always have a gyro sensorMask |= BOARD_SENSOR_GYRO; // Autodetect gyro hardware. We have MPU3050 or MPU6050. if (mpu6050Detect(&acc, &gyro, gyro_lpf, &gyro_scale)) { // this filled up acc.* struct with init values haveMpu6k = true; } else if (l3g4200dDetect(&gyro, gyro_lpf)) { // well, we found our gyro ; } else if (!mpu3050Detect(&gyro, gyro_lpf)) { // if this fails, we get a beep + blink pattern. we're doomed, no gyro or i2c error. boardFault( BOARD_FAULT_FATAL ); } // Accelerometer. F**k it. Let user break shit. retryAcc: switch (accHardware) { case 0: // autodetect case 1: // MPU6050 if (haveMpu6k) { //acc struct already filled from previous gyro detection // PB13 - MPU_INT output on rev4 hardware GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); goto validAcc; } case 2: // ADXL345 acc_params.useFifo = false; acc_params.dataRate = 800; // unused currently if (adxl345Detect(&acc_params, &acc) ) goto validAcc; //Fallthrough to the next one case 3: // MMA8452 if (mma8452Detect(&acc)) { //Some gpio magic to trigger an init GPIO_InitTypeDef GPIO_InitStructure; // PA5 - ACC_INT2 output on rev3/4 hardware // OLIMEXINO - The PA5 pin is wired up to LED1, if you need to use an mma8452 on an Olimexino use a different pin and provide support in code. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); goto validAcc; } default: //nothing found, seems there's no ACC goto skipAcc; } accHardware++; goto retryAcc; validAcc: sensorMask |= BOARD_SENSOR_ACC; //Found a valid acc, init it acc.init(); skipAcc: #ifdef BARO GPIO_InitTypeDef GPIO_InitStructure; // PC13 (BMP085's XCLR reset input, which we use to disable it) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); BMP085_OFF; // Detect what pressure sensors are available. baro->update() is set to sensor-specific update function // ms5611 disables BMP085, and tries to initialize + check PROM crc. if this works, we have a baro if ( ms5611Detect(&baro) || bmp085Detect(&baro) ) { sensorMask |= BOARD_SENSOR_BARO; } #endif // this is safe because either mpu6050 or mpu3050 or lg3d20 sets it, and in case of fail, we never get here. gyro.init(); if ( hmc5883lDetect() ) { sensorMask |= BOARD_SENSOR_MAG; } // calculate magnetic declination // deg = cfg.mag_declination / 100; // min = cfg.mag_declination % 100; // magneticDeclination = (deg + ((float)min * (1.0f / 60.0f))) * 10; // heading is in 0.1deg units }