static void sensorsSetupSlaveRead(void) { // Now begin to set up the slaves #ifdef SENSORS_MPU6500_DLPF_256HZ // As noted in registersheet 4.4: "Data should be sampled at or above sample rate; // SMPLRT_DIV is only used for 1kHz internal sampling." Slowest update rate is then 500Hz. mpu6500SetSlave4MasterDelay(15); // read slaves at 500Hz = (8000Hz / (1 + 15)) #else mpu6500SetSlave4MasterDelay(9); // read slaves at 100Hz = (500Hz / (1 + 4)) #endif mpu6500SetI2CBypassEnabled(false); mpu6500SetWaitForExternalSensorEnabled(true); // the slave data isn't so important for the state estimation mpu6500SetInterruptMode(0); // active high mpu6500SetInterruptDrive(0); // push pull mpu6500SetInterruptLatch(0); // latched until clear mpu6500SetInterruptLatchClear(1); // cleared on any register read mpu6500SetSlaveReadWriteTransitionEnabled(false); // Send a stop at the end of a slave read mpu6500SetMasterClockSpeed(13); // Set i2c speed to 400kHz #ifdef SENSORS_ENABLE_MAG_AK8963 if (isMagnetometerPresent) { // Set registers for MPU6500 master to read from mpu6500SetSlaveAddress(0, 0x80 | AK8963_ADDRESS_00); // set the magnetometer to Slave 0, enable read mpu6500SetSlaveRegister(0, AK8963_RA_ST1); // read the magnetometer heading register mpu6500SetSlaveDataLength(0, SENSORS_MAG_BUFF_LEN); // read 8 bytes (ST1, x, y, z heading, ST2 (overflow check)) mpu6500SetSlaveDelayEnabled(0, true); mpu6500SetSlaveEnabled(0, true); } #endif #ifdef SENSORS_ENABLE_PRESSURE_LPS25H if (isBarometerPresent) { // Configure the LPS25H as a slave and enable read // Setting up two reads works for LPS25H fifo avg filter as well as the // auto inc wraps back to LPS25H_PRESS_OUT_L after LPS25H_PRESS_OUT_H is read. mpu6500SetSlaveAddress(1, 0x80 | LPS25H_I2C_ADDR); mpu6500SetSlaveRegister(1, LPS25H_STATUS_REG | LPS25H_ADDR_AUTO_INC); mpu6500SetSlaveDataLength(1, SENSORS_BARO_BUFF_S_P_LEN); mpu6500SetSlaveDelayEnabled(1, true); mpu6500SetSlaveEnabled(1, true); mpu6500SetSlaveAddress(2, 0x80 | LPS25H_I2C_ADDR); mpu6500SetSlaveRegister(2, LPS25H_TEMP_OUT_L | LPS25H_ADDR_AUTO_INC); mpu6500SetSlaveDataLength(2, SENSORS_BARO_BUFF_T_LEN); mpu6500SetSlaveDelayEnabled(2, true); mpu6500SetSlaveEnabled(2, true); } #endif // Enable sensors after configuration mpu6500SetI2CMasterModeEnabled(true); mpu6500SetIntDataReadyEnabled(true); }
static void sensorsDeviceInit(void) { isMagnetometerPresent = false; isBarometerPresent = false; // Wait for sensors to startup while (xTaskGetTickCount() < 1000); i2cdevInit(I2C3_DEV); mpu6500Init(I2C3_DEV); if (mpu6500TestConnection() == true) { DEBUG_PRINT("MPU9250 I2C connection [OK].\n"); } else { DEBUG_PRINT("MPU9250 I2C connection [FAIL].\n"); } mpu6500Reset(); vTaskDelay(M2T(50)); // Activate MPU6500 mpu6500SetSleepEnabled(false); // Enable temp sensor mpu6500SetTempSensorEnabled(true); // Disable interrupts mpu6500SetIntEnabled(false); // Connect the HMC5883L to the main I2C bus mpu6500SetI2CBypassEnabled(true); // Set x-axis gyro as clock source mpu6500SetClockSource(MPU6500_CLOCK_PLL_XGYRO); // Set gyro full scale range mpu6500SetFullScaleGyroRange(IMU_GYRO_FS_CFG); // Set accelerometer full scale range mpu6500SetFullScaleAccelRange(IMU_ACCEL_FS_CFG); #ifdef IMU_MPU6500_DLPF_256HZ // 256Hz digital low-pass filter only works with little vibrations // Set output rate (15): 8000 / (1 + 15) = 500Hz mpu6500SetRate(15); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_256); #else // To low DLPF bandwidth might cause instability and decrease agility // but it works well for handling vibrations and unbalanced propellers // Set output rate (1): 1000 / (1 + 1) = 500Hz mpu6500SetRate(1); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_98); #endif // delay 3 seconds until the quad has stabilized enough to pass the test bool mpu6500SelfTestPassed = false; for (int i=0; i<300; i++) { if(mpu6500SelfTest() == true) { mpu6500SelfTestPassed = true; break; } else { vTaskDelay(M2T(10)); } } configASSERT(mpu6500SelfTestPassed); // Now begin to set up the slaves mpu6500SetSlave4MasterDelay(4); // read slaves at 100Hz = (500Hz / (1 + 4)) #ifdef IMU_ENABLE_MAG_AK8963 ak8963Init(I2C3_DEV); if (ak8963TestConnection() == true) { isMagnetometerPresent = true; ak8963SetMode(AK8963_MODE_16BIT | AK8963_MODE_CONT2); // 16bit 100Hz configASSERT(ak8963SelfTest()); DEBUG_PRINT("AK8963 I2C connection [OK].\n"); mpu6500SetSlaveAddress(0, 0x80 | AK8963_ADDRESS_00); // set the magnetometer to Slave 0, enable read mpu6500SetSlaveRegister(0, AK8963_RA_HXL); // read the magnetometer heading register mpu6500SetSlaveDataLength(0, 6); // read 6 bytes (x, y, z heading) mpu6500SetSlaveDelayEnabled(0, true); mpu6500SetSlaveEnabled(0, true); } else { DEBUG_PRINT("AK8963 I2C connection [FAIL].\n"); } #endif #ifdef IMU_ENABLE_PRESSURE_LPS25H lps25hInit(I2C3_DEV); if (lps25hTestConnection() == true) { lps25hSetEnabled(true); isBarometerPresent = true; configASSERT(lps25hSelfTest()); DEBUG_PRINT("LPS25H I2C connection [OK].\n"); mpu6500SetSlaveAddress(1, 0x80 | LPS25H_I2C_ADDR); // set the barometer to Slave 1, enable read mpu6500SetSlaveRegister(1, LPS25H_PRESS_OUT_XL | LPS25H_ADDR_AUTO_INC); mpu6500SetSlaveDataLength(1, 5); mpu6500SetSlaveDelayEnabled(1, true); mpu6500SetSlaveEnabled(1, true); } else { //TODO: Should sensor test fail hard if no connection DEBUG_PRINT("LPS25H I2C connection [FAIL].\n"); } #endif mpu6500SetI2CBypassEnabled(false); mpu6500SetI2CMasterModeEnabled(true); mpu6500SetWaitForExternalSensorEnabled(false); // the slave data isn't so important for the state estimation mpu6500SetInterruptMode(0); // active high mpu6500SetInterruptDrive(0); // push pull mpu6500SetInterruptLatch(0); // latched until clear mpu6500SetInterruptLatchClear(1); // cleared on any register read mpu6500SetIntDataReadyEnabled(true); }