mirror of
https://github.com/iNavFlight/inav.git
synced 2025-07-22 15:55:40 +03:00
PCA9685 PWM driver support (#261)
* 1st stage of PCA9685 PWM driver support * Servo output to PCA9685 in NAZE target. * FEATURE_PWM_SERVO_DRIVER introduced * task for PWM driver * abstraction layer for pwm drivers * feature enabled only on target with >128 flash
This commit is contained in:
parent
46fee424be
commit
425c6e6499
16 changed files with 270 additions and 5 deletions
3
Makefile
3
Makefile
|
@ -398,6 +398,7 @@ COMMON_SRC = \
|
||||||
drivers/sound_beeper.c \
|
drivers/sound_beeper.c \
|
||||||
drivers/system.c \
|
drivers/system.c \
|
||||||
drivers/timer.c \
|
drivers/timer.c \
|
||||||
|
drivers/io_pca9685.c \
|
||||||
flight/failsafe.c \
|
flight/failsafe.c \
|
||||||
flight/imu.c \
|
flight/imu.c \
|
||||||
flight/hil.c \
|
flight/hil.c \
|
||||||
|
@ -414,6 +415,7 @@ COMMON_SRC = \
|
||||||
io/serial_msp.c \
|
io/serial_msp.c \
|
||||||
io/statusindicator.c \
|
io/statusindicator.c \
|
||||||
fc/msp_server_fc.c \
|
fc/msp_server_fc.c \
|
||||||
|
io/pwmdriver_i2c.c \
|
||||||
rx/ibus.c \
|
rx/ibus.c \
|
||||||
rx/jetiexbus.c \
|
rx/jetiexbus.c \
|
||||||
rx/msp.c \
|
rx/msp.c \
|
||||||
|
@ -567,7 +569,6 @@ TARGET_SRC += $(VCP_SRC)
|
||||||
endif
|
endif
|
||||||
# end target specific make file checks
|
# end target specific make file checks
|
||||||
|
|
||||||
|
|
||||||
# Search path and source files for the ST stdperiph library
|
# Search path and source files for the ST stdperiph library
|
||||||
VPATH := $(VPATH):$(STDPERIPH_DIR)/src
|
VPATH := $(VPATH):$(STDPERIPH_DIR)/src
|
||||||
|
|
||||||
|
|
|
@ -883,6 +883,10 @@ void validateAndFixConfig(void)
|
||||||
#endif // CC3D_PPM1
|
#endif // CC3D_PPM1
|
||||||
#endif // CC3D
|
#endif // CC3D
|
||||||
|
|
||||||
|
#ifndef USE_PMW_SERVO_DRIVER
|
||||||
|
featureClear(FEATURE_PWM_SERVO_DRIVER);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(COLIBRI_RACE)
|
#if defined(COLIBRI_RACE)
|
||||||
masterConfig.serialConfig.portConfigs[0].functionMask = FUNCTION_MSP;
|
masterConfig.serialConfig.portConfigs[0].functionMask = FUNCTION_MSP;
|
||||||
if(featureConfigured(FEATURE_RX_SERIAL)) {
|
if(featureConfigured(FEATURE_RX_SERIAL)) {
|
||||||
|
|
|
@ -54,6 +54,7 @@ typedef enum {
|
||||||
FEATURE_VTX = 1 << 24,
|
FEATURE_VTX = 1 << 24,
|
||||||
FEATURE_RX_SPI = 1 << 25,
|
FEATURE_RX_SPI = 1 << 25,
|
||||||
FEATURE_SOFTSPI = 1 << 26,
|
FEATURE_SOFTSPI = 1 << 26,
|
||||||
|
FEATURE_PWM_SERVO_DRIVER = 1 << 27,
|
||||||
} features_e;
|
} features_e;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
129
src/main/drivers/io_pca9685.c
Normal file
129
src/main/drivers/io_pca9685.c
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <platform.h>
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "bus_i2c.h"
|
||||||
|
|
||||||
|
#include "common/maths.h"
|
||||||
|
|
||||||
|
#include "config/config.h"
|
||||||
|
#include "fc/runtime_config.h"
|
||||||
|
|
||||||
|
#define PCA9685_ADDR 0x40
|
||||||
|
#define PCA9685_MODE1 0x00
|
||||||
|
#define PCA9685_PRESCALE 0xFE
|
||||||
|
|
||||||
|
#define LED0_ON_L 0x06
|
||||||
|
#define LED0_ON_H 0x07
|
||||||
|
#define LED0_OFF_L 0x08
|
||||||
|
#define LED0_OFF_H 0x09
|
||||||
|
|
||||||
|
#define PCA9685_SERVO_FREQUENCY 60
|
||||||
|
#define PCA9685_SERVO_COUNT 16
|
||||||
|
#define PCA9685_SYNC_THRESHOLD 5
|
||||||
|
|
||||||
|
uint16_t currentOutputState[PCA9685_SERVO_FREQUENCY] = {0};
|
||||||
|
uint16_t temporaryOutputState[PCA9685_SERVO_FREQUENCY] = {0};
|
||||||
|
|
||||||
|
void pca9685setPWMOn(uint8_t servoIndex, uint16_t on) {
|
||||||
|
if (servoIndex < PCA9685_SERVO_COUNT) {
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, LED0_ON_L + (servoIndex * 4), on);
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, LED0_ON_H + (servoIndex * 4), on>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pca9685setPWMOff(uint8_t servoIndex, uint16_t off) {
|
||||||
|
if (servoIndex < PCA9685_SERVO_COUNT) {
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, LED0_OFF_L + (servoIndex * 4), off);
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, LED0_OFF_H + (servoIndex * 4), off>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Writing new state every cycle for each servo is extremely time consuming
|
||||||
|
and does not makes sense.
|
||||||
|
On Flip32/Naze32 trying to sync 5 servos every 2000us extends looptime
|
||||||
|
to 3500us. Very, very bad...
|
||||||
|
Instead of that, write desired values to temporary
|
||||||
|
table and write it to PCA9685 only when there a need.
|
||||||
|
Also, because of resultion of PCA9685 internal counter of about 5us, do not write
|
||||||
|
small changes, since thwy will only clog the bandwidch and will not
|
||||||
|
be represented on output
|
||||||
|
PWM Driver runs at 200Hz, every cycle every 4th servo output is updated:
|
||||||
|
cycle 0: servo 0, 4, 8, 12
|
||||||
|
cycle 1: servo 1, 5, 9, 13
|
||||||
|
cycle 2: servo 2, 6, 10, 14
|
||||||
|
cycle 3: servo3, 7, 11, 15
|
||||||
|
*/
|
||||||
|
void pca9685sync(uint8_t cycleIndex) {
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < PCA9685_SERVO_COUNT; i++) {
|
||||||
|
if (cycleIndex == i % 4 && ABS(temporaryOutputState[i] - currentOutputState[i]) > PCA9685_SYNC_THRESHOLD) {
|
||||||
|
pca9685setPWMOff(i, temporaryOutputState[i]);
|
||||||
|
currentOutputState[i] = temporaryOutputState[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pca9685setServoPulse(uint8_t servoIndex, uint16_t pulse) {
|
||||||
|
|
||||||
|
static double pulselength = 0;
|
||||||
|
|
||||||
|
if (pulselength == 0) {
|
||||||
|
pulselength = 1000000; // 1,000,000 us per second
|
||||||
|
pulselength /= PCA9685_SERVO_FREQUENCY;
|
||||||
|
pulselength /= 4096; // 12 bits of resolution
|
||||||
|
}
|
||||||
|
pulse /= pulselength;
|
||||||
|
|
||||||
|
temporaryOutputState[servoIndex] = pulse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pca9685setPWMFreq(uint16_t freq) {
|
||||||
|
|
||||||
|
uint32_t prescaleval = 25000000;
|
||||||
|
prescaleval /= 4096;
|
||||||
|
prescaleval /= freq;
|
||||||
|
prescaleval -= 1;
|
||||||
|
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, PCA9685_MODE1, 16);
|
||||||
|
delay(1);
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, PCA9685_PRESCALE, (uint8_t) prescaleval);
|
||||||
|
delay(1);
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, PCA9685_MODE1, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pca9685Initialize(void) {
|
||||||
|
|
||||||
|
bool ack = false;
|
||||||
|
uint8_t sig;
|
||||||
|
|
||||||
|
ack = i2cRead(I2C_DEVICE, PCA9685_ADDR, PCA9685_MODE1, 1, &sig);
|
||||||
|
|
||||||
|
if (!ack) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
Reset device
|
||||||
|
*/
|
||||||
|
i2cWrite(I2C_DEVICE, PCA9685_ADDR, PCA9685_MODE1, 0x0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set refresh rate
|
||||||
|
*/
|
||||||
|
pca9685setPWMFreq(PCA9685_SERVO_FREQUENCY);
|
||||||
|
|
||||||
|
delay(1);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < PCA9685_SERVO_COUNT; i++) {
|
||||||
|
pca9685setPWMOn(i, 0);
|
||||||
|
pca9685setPWMOff(i, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
6
src/main/drivers/io_pca9685.h
Normal file
6
src/main/drivers/io_pca9685.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
bool pca9685Initialize(void);
|
||||||
|
void pca9685setPWMOn(uint8_t servoIndex, uint16_t on);
|
||||||
|
void pca9685setPWMOff(uint8_t servoIndex, uint16_t off);
|
||||||
|
void pca9685setPWMFreq(float freq);
|
||||||
|
void pca9685setServoPulse(uint8_t servoIndex, uint16_t pulse);
|
||||||
|
void pca9685sync(uint8_t cycleIndex);
|
|
@ -28,6 +28,10 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "pwm_mapping.h"
|
#include "pwm_mapping.h"
|
||||||
#include "pwm_output.h"
|
#include "pwm_output.h"
|
||||||
|
#include "drivers/io_pca9685.h"
|
||||||
|
#include "io/pwmdriver_i2c.h"
|
||||||
|
#include "config/config.h"
|
||||||
|
#include "fc/runtime_config.h"
|
||||||
|
|
||||||
typedef void (*pwmWriteFuncPtr)(uint8_t index, uint16_t value); // function pointer used to write motors
|
typedef void (*pwmWriteFuncPtr)(uint8_t index, uint16_t value); // function pointer used to write motors
|
||||||
|
|
||||||
|
@ -129,7 +133,7 @@ static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timerHardware, uint8
|
||||||
p->tim = timerHardware->tim;
|
p->tim = timerHardware->tim;
|
||||||
|
|
||||||
*p->ccr = 0;
|
*p->ccr = 0;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +223,18 @@ void pwmServoConfig(const timerHardware_t *timerHardware, uint8_t servoIndex, ui
|
||||||
|
|
||||||
void pwmWriteServo(uint8_t index, uint16_t value)
|
void pwmWriteServo(uint8_t index, uint16_t value)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
|
||||||
|
if (feature(FEATURE_PWM_SERVO_DRIVER)) {
|
||||||
|
pwmDriverSetPulse(index, value);
|
||||||
|
} else if (servos[index] && index < MAX_SERVOS) {
|
||||||
|
*servos[index]->ccr = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
if (servos[index] && index < MAX_SERVOS) {
|
if (servos[index] && index < MAX_SERVOS) {
|
||||||
*servos[index]->ccr = value;
|
*servos[index]->ccr = value;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,6 +88,9 @@
|
||||||
#include "config/config_master.h"
|
#include "config/config_master.h"
|
||||||
#include "config/feature.h"
|
#include "config/feature.h"
|
||||||
|
|
||||||
|
#include "io/pwmdriver_i2c.h"
|
||||||
|
#include "drivers/io_pca9685.h"
|
||||||
|
|
||||||
// June 2013 V2.2-dev
|
// June 2013 V2.2-dev
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -632,6 +635,7 @@ void taskMainPidLoop(void)
|
||||||
handleBlackbox();
|
handleBlackbox();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for loop trigger
|
// Function for loop trigger
|
||||||
|
@ -774,3 +778,12 @@ void taskLedStrip(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
void taskSyncPwmDriver(void) {
|
||||||
|
|
||||||
|
if (feature(FEATURE_PWM_SERVO_DRIVER)) {
|
||||||
|
pwmDriverSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
57
src/main/io/pwmdriver_i2c.c
Normal file
57
src/main/io/pwmdriver_i2c.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "drivers/io_pca9685.h"
|
||||||
|
|
||||||
|
#include "config/config.h"
|
||||||
|
#include "fc/runtime_config.h"
|
||||||
|
#include "config/feature.h"
|
||||||
|
|
||||||
|
#define PWM_DRIVER_IMPLEMENTATION_COUNT 1
|
||||||
|
#define PWM_DRIVER_MAX_CYCLE 4
|
||||||
|
|
||||||
|
static bool driverEnabled = false;
|
||||||
|
static uint8_t driverImplementationIndex = 0;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool (*initFunction)(void);
|
||||||
|
void (*writeFunction)(uint8_t servoIndex, uint16_t off);
|
||||||
|
void (*setFrequencyFunction)(float freq);
|
||||||
|
void (*syncFunction)(uint8_t cycleIndex);
|
||||||
|
} pwmDriverDriver_t;
|
||||||
|
|
||||||
|
pwmDriverDriver_t pwmDrivers[PWM_DRIVER_IMPLEMENTATION_COUNT] = {
|
||||||
|
[0] = {
|
||||||
|
.initFunction = pca9685Initialize,
|
||||||
|
.writeFunction = pca9685setServoPulse,
|
||||||
|
.setFrequencyFunction = pca9685setPWMFreq,
|
||||||
|
.syncFunction = pca9685sync
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isPwmDriverEnabled() {
|
||||||
|
return driverEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pwmDriverSetPulse(uint8_t servoIndex, uint16_t length) {
|
||||||
|
(pwmDrivers[driverImplementationIndex].writeFunction)(servoIndex, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pwmDriverInitialize(void) {
|
||||||
|
driverEnabled = (pwmDrivers[driverImplementationIndex].initFunction)();
|
||||||
|
|
||||||
|
if (!driverEnabled) {
|
||||||
|
featureClear(FEATURE_PWM_SERVO_DRIVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void pwmDriverSync(void) {
|
||||||
|
static uint8_t cycle = 0;
|
||||||
|
|
||||||
|
(pwmDrivers[driverImplementationIndex].syncFunction)(cycle);
|
||||||
|
|
||||||
|
cycle++;
|
||||||
|
if (cycle == PWM_DRIVER_MAX_CYCLE) {
|
||||||
|
cycle = 0;
|
||||||
|
}
|
||||||
|
}
|
4
src/main/io/pwmdriver_i2c.h
Normal file
4
src/main/io/pwmdriver_i2c.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
void pwmDriverInitialize(void);
|
||||||
|
void pwmDriverSync(void);
|
||||||
|
void pwmDriverSetPulse(uint8_t servoIndex, uint16_t length);
|
|
@ -212,7 +212,7 @@ static const char * const featureNames[] = {
|
||||||
"SONAR", "TELEMETRY", "CURRENT_METER", "3D", "RX_PARALLEL_PWM",
|
"SONAR", "TELEMETRY", "CURRENT_METER", "3D", "RX_PARALLEL_PWM",
|
||||||
"RX_MSP", "RSSI_ADC", "LED_STRIP", "DISPLAY", "ONESHOT125",
|
"RX_MSP", "RSSI_ADC", "LED_STRIP", "DISPLAY", "ONESHOT125",
|
||||||
"BLACKBOX", "CHANNEL_FORWARDING", "TRANSPONDER", "AIRMODE",
|
"BLACKBOX", "CHANNEL_FORWARDING", "TRANSPONDER", "AIRMODE",
|
||||||
"SUPEREXPO", "VTX", "RX_SPI", "SOFTSPI", NULL
|
"SUPEREXPO", "VTX", "RX_SPI", "SOFTSPI", "PWM_SERVO_DRIVER", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
// sync this with rxFailsafeChannelMode_e
|
// sync this with rxFailsafeChannelMode_e
|
||||||
|
|
|
@ -62,6 +62,8 @@
|
||||||
#include "drivers/gyro_sync.h"
|
#include "drivers/gyro_sync.h"
|
||||||
#include "drivers/io.h"
|
#include "drivers/io.h"
|
||||||
#include "drivers/exti.h"
|
#include "drivers/exti.h"
|
||||||
|
#include "io/pwmdriver_i2c.h"
|
||||||
|
#include "drivers/io_pca9685.h"
|
||||||
|
|
||||||
#include "rx/rx.h"
|
#include "rx/rx.h"
|
||||||
#include "rx/spektrum.h"
|
#include "rx/spektrum.h"
|
||||||
|
@ -282,6 +284,16 @@ void init(void)
|
||||||
pwmRxInit(masterConfig.inputFilteringMode);
|
pwmRxInit(masterConfig.inputFilteringMode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
/*
|
||||||
|
If external PWM driver is enabled, for example PCA9685, disable internal
|
||||||
|
servo handling mechanism, since external device will do that
|
||||||
|
*/
|
||||||
|
if (feature(FEATURE_PWM_SERVO_DRIVER)) {
|
||||||
|
pwm_params.useServos = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// pwmInit() needs to be called as soon as possible for ESC compatibility reasons
|
// pwmInit() needs to be called as soon as possible for ESC compatibility reasons
|
||||||
pwmInit(&pwm_params);
|
pwmInit(&pwm_params);
|
||||||
|
|
||||||
|
@ -573,6 +585,10 @@ void init(void)
|
||||||
LED2_ON;
|
LED2_ON;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
pwmDriverInitialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Latch active features AGAIN since some may be modified by init().
|
// Latch active features AGAIN since some may be modified by init().
|
||||||
latchActiveFeatures();
|
latchActiveFeatures();
|
||||||
motorControlEnable = true;
|
motorControlEnable = true;
|
||||||
|
@ -637,6 +653,10 @@ int main(void)
|
||||||
setTaskEnabled(TASK_LEDSTRIP, feature(FEATURE_LED_STRIP));
|
setTaskEnabled(TASK_LEDSTRIP, feature(FEATURE_LED_STRIP));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
setTaskEnabled(TASK_PWMDRIVER, feature(FEATURE_PWM_SERVO_DRIVER));
|
||||||
|
#endif
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
scheduler();
|
scheduler();
|
||||||
processLoopback();
|
processLoopback();
|
||||||
|
|
|
@ -68,6 +68,9 @@ typedef enum {
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
TASK_LEDSTRIP,
|
TASK_LEDSTRIP,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
TASK_PWMDRIVER,
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Count of real tasks */
|
/* Count of real tasks */
|
||||||
TASK_COUNT,
|
TASK_COUNT,
|
||||||
|
|
|
@ -129,4 +129,14 @@ cfTask_t cfTasks[TASK_COUNT] = {
|
||||||
.staticPriority = TASK_PRIORITY_IDLE,
|
.staticPriority = TASK_PRIORITY_IDLE,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
[TASK_PWMDRIVER] = {
|
||||||
|
.taskName = "PWMDRIVER",
|
||||||
|
.taskFunc = taskSyncPwmDriver,
|
||||||
|
.desiredPeriod = 1000000 / 200, // 200 Hz
|
||||||
|
.staticPriority = TASK_PRIORITY_HIGH,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,4 +33,6 @@ void taskUpdateDisplay(void);
|
||||||
void taskTelemetry(void);
|
void taskTelemetry(void);
|
||||||
void taskLedStrip(void);
|
void taskLedStrip(void);
|
||||||
void taskSystem(void);
|
void taskSystem(void);
|
||||||
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
|
void taskSyncPwmDriver(void);
|
||||||
|
#endif
|
||||||
|
|
|
@ -787,4 +787,3 @@ bool sensorsAutodetect(sensorAlignmentConfig_t *sensorAlignmentConfig,
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
#define TELEMETRY_MAVLINK
|
#define TELEMETRY_MAVLINK
|
||||||
#define BOOTLOG_DESCRIPTIONS
|
#define BOOTLOG_DESCRIPTIONS
|
||||||
#define TELEMETRY_IBUS
|
#define TELEMETRY_IBUS
|
||||||
|
#define USE_PMW_SERVO_DRIVER
|
||||||
|
#define PWM_DRIVER_PCA9685
|
||||||
#else
|
#else
|
||||||
#define SKIP_CLI_COMMAND_HELP
|
#define SKIP_CLI_COMMAND_HELP
|
||||||
#define SKIP_RX_MSP
|
#define SKIP_RX_MSP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue