bool compassDetect(magDev_t *dev) { magSensor_e magHardware = MAG_NONE; busDevice_t *busdev = &dev->busdev; #ifdef USE_MAG_DATA_READY_SIGNAL dev->magIntExtiTag = compassConfig()->interruptTag; #endif switch (compassConfig()->mag_bustype) { #ifdef USE_I2C case BUSTYPE_I2C: busdev->bustype = BUSTYPE_I2C; busdev->busdev_u.i2c.device = I2C_CFG_TO_DEV(compassConfig()->mag_i2c_device); busdev->busdev_u.i2c.address = compassConfig()->mag_i2c_address; #endif break; #ifdef USE_SPI case BUSTYPE_SPI: busdev->bustype = BUSTYPE_SPI; spiBusSetInstance(busdev, spiInstanceByDevice(SPI_CFG_TO_DEV(compassConfig()->mag_spi_device))); busdev->busdev_u.spi.csnPin = IOGetByTag(compassConfig()->mag_spi_csn); #endif break; #if defined(USE_MAG_AK8963) && (defined(USE_GYRO_SPI_MPU6500) || defined(USE_GYRO_SPI_MPU9250)) case BUSTYPE_MPU_SLAVE: { if (gyroMpuDetectionResult()->sensor == MPU_9250_SPI) { busdev->bustype = BUSTYPE_MPU_SLAVE; busdev->busdev_u.mpuSlave.master = gyroSensorBus(); busdev->busdev_u.mpuSlave.address = compassConfig()->mag_i2c_address; } else { return false; } } #endif break; default: return false; } dev->magAlign = ALIGN_DEFAULT; switch (compassConfig()->mag_hardware) { case MAG_DEFAULT: FALLTHROUGH; case MAG_HMC5883: #if defined(USE_MAG_HMC5883) || defined(USE_MAG_SPI_HMC5883) if (busdev->bustype == BUSTYPE_I2C) { busdev->busdev_u.i2c.address = compassConfig()->mag_i2c_address; } if (hmc5883lDetect(dev)) { #ifdef MAG_HMC5883_ALIGN dev->magAlign = MAG_HMC5883_ALIGN; #endif magHardware = MAG_HMC5883; break; } #endif FALLTHROUGH; case MAG_AK8975: #ifdef USE_MAG_AK8975 if (busdev->bustype == BUSTYPE_I2C) { busdev->busdev_u.i2c.address = compassConfig()->mag_i2c_address; } if (ak8975Detect(dev)) { #ifdef MAG_AK8975_ALIGN dev->magAlign = MAG_AK8975_ALIGN; #endif magHardware = MAG_AK8975; break; } #endif FALLTHROUGH; case MAG_AK8963: #if defined(USE_MAG_AK8963) || defined(USE_MAG_SPI_AK8963) if (busdev->bustype == BUSTYPE_I2C) { busdev->busdev_u.i2c.address = compassConfig()->mag_i2c_address; } if (gyroMpuDetectionResult()->sensor == MPU_9250_SPI) { dev->busdev.bustype = BUSTYPE_MPU_SLAVE; busdev->busdev_u.mpuSlave.address = compassConfig()->mag_i2c_address; dev->busdev.busdev_u.mpuSlave.master = gyroSensorBus(); } if (ak8963Detect(dev)) { #ifdef MAG_AK8963_ALIGN dev->magAlign = MAG_AK8963_ALIGN; #endif magHardware = MAG_AK8963; break; } #endif FALLTHROUGH; case MAG_NONE: magHardware = MAG_NONE; break; } if (magHardware == MAG_NONE) { return false; } detectedSensors[SENSOR_INDEX_MAG] = magHardware; sensorsSet(SENSOR_MAG); return true; }
void validateAndFixGyroConfig(void) { // Prevent invalid notch cutoff if (gyroConfig()->gyro_soft_notch_cutoff_1 >= gyroConfig()->gyro_soft_notch_hz_1) { gyroConfigMutable()->gyro_soft_notch_hz_1 = 0; } if (gyroConfig()->gyro_soft_notch_cutoff_2 >= gyroConfig()->gyro_soft_notch_hz_2) { gyroConfigMutable()->gyro_soft_notch_hz_2 = 0; } if (gyroConfig()->gyro_lpf != GYRO_LPF_256HZ && gyroConfig()->gyro_lpf != GYRO_LPF_NONE) { pidConfigMutable()->pid_process_denom = 1; // When gyro set to 1khz always set pid speed 1:1 to sampling speed gyroConfigMutable()->gyro_sync_denom = 1; gyroConfigMutable()->gyro_use_32khz = false; } if (gyroConfig()->gyro_use_32khz) { // F1 and F3 can't handle high sample speed. #if defined(STM32F1) gyroConfigMutable()->gyro_sync_denom = MAX(gyroConfig()->gyro_sync_denom, 16); #elif defined(STM32F3) gyroConfigMutable()->gyro_sync_denom = MAX(gyroConfig()->gyro_sync_denom, 4); #endif } else { #if defined(STM32F1) gyroConfigMutable()->gyro_sync_denom = MAX(gyroConfig()->gyro_sync_denom, 3); #endif } float samplingTime; switch (gyroMpuDetectionResult()->sensor) { case ICM_20649_SPI: samplingTime = 1.0f / 9000.0f; break; case BMI_160_SPI: samplingTime = 0.0003125f; break; default: samplingTime = 0.000125f; break; } if (gyroConfig()->gyro_lpf != GYRO_LPF_256HZ && gyroConfig()->gyro_lpf != GYRO_LPF_NONE) { switch (gyroMpuDetectionResult()->sensor) { case ICM_20649_SPI: samplingTime = 1.0f / 1100.0f; break; default: samplingTime = 0.001f; break; } } if (gyroConfig()->gyro_use_32khz) { samplingTime = 0.00003125; } // check for looptime restrictions based on motor protocol. Motor times have safety margin float motorUpdateRestriction; switch (motorConfig()->dev.motorPwmProtocol) { case PWM_TYPE_STANDARD: motorUpdateRestriction = 1.0f / BRUSHLESS_MOTORS_PWM_RATE; break; case PWM_TYPE_ONESHOT125: motorUpdateRestriction = 0.0005f; break; case PWM_TYPE_ONESHOT42: motorUpdateRestriction = 0.0001f; break; #ifdef USE_DSHOT case PWM_TYPE_DSHOT150: motorUpdateRestriction = 0.000250f; break; case PWM_TYPE_DSHOT300: motorUpdateRestriction = 0.0001f; break; #endif default: motorUpdateRestriction = 0.00003125f; break; } if (motorConfig()->dev.useUnsyncedPwm) { // Prevent overriding the max rate of motors if ((motorConfig()->dev.motorPwmProtocol <= PWM_TYPE_BRUSHED) && (motorConfig()->dev.motorPwmProtocol != PWM_TYPE_STANDARD)) { const uint32_t maxEscRate = lrintf(1.0f / motorUpdateRestriction); motorConfigMutable()->dev.motorPwmRate = MIN(motorConfig()->dev.motorPwmRate, maxEscRate); } } else { const float pidLooptime = samplingTime * gyroConfig()->gyro_sync_denom * pidConfig()->pid_process_denom; if (pidLooptime < motorUpdateRestriction) { const uint8_t minPidProcessDenom = constrain(motorUpdateRestriction / (samplingTime * gyroConfig()->gyro_sync_denom), 1, MAX_PID_PROCESS_DENOM); pidConfigMutable()->pid_process_denom = MAX(pidConfigMutable()->pid_process_denom, minPidProcessDenom); } } }