mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 22:35:23 +03:00
TIM8 correctly. Software serial conficted with parallel PWM input. Fixed crash due to incorrect timerConfig index calculation code. The crash occurred when capture compare interrupt handlers attempted to call an invalid callback. Note: the crash does not affect existing baseflight code since the formula is OK when using a 2 dimensional array with equal dimensions. Formula details here: https://docs.google.com/spreadsheets/d/1UuxnC0VKiprvt1wt3KXffefEWJUb_-ILFLQuP377Anw
242 lines
7.8 KiB
C
Executable file
242 lines
7.8 KiB
C
Executable file
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "platform.h"
|
|
|
|
#include "common/axis.h"
|
|
|
|
#include "drivers/system_common.h"
|
|
#include "drivers/gpio_common.h"
|
|
#include "drivers/light_led.h"
|
|
#include "drivers/sound_beeper.h"
|
|
#include "drivers/timer_common.h"
|
|
#include "drivers/serial_common.h"
|
|
#include "drivers/serial_softserial.h"
|
|
#include "drivers/serial_uart.h"
|
|
#include "drivers/accgyro_common.h"
|
|
#include "drivers/pwm_common.h"
|
|
#include "drivers/adc_common.h"
|
|
|
|
#include "flight_common.h"
|
|
#include "flight_mixer.h"
|
|
|
|
#include "serial_common.h"
|
|
#include "failsafe.h"
|
|
|
|
#include "gps_common.h"
|
|
#include "escservo.h"
|
|
#include "rc_controls.h"
|
|
#include "rx_common.h"
|
|
#include "gimbal.h"
|
|
#include "sensors_common.h"
|
|
#include "sensors_sonar.h"
|
|
#include "sensors_barometer.h"
|
|
#include "sensors_acceleration.h"
|
|
#include "sensors_gyro.h"
|
|
#include "telemetry_common.h"
|
|
#include "battery.h"
|
|
#include "boardalignment.h"
|
|
#include "runtime_config.h"
|
|
#include "config.h"
|
|
#include "config_profile.h"
|
|
#include "config_master.h"
|
|
|
|
#include "build_config.h"
|
|
|
|
extern rcReadRawDataPtr rcReadRawFunc;
|
|
|
|
extern uint32_t previousTime;
|
|
|
|
failsafe_t *failsafe;
|
|
|
|
void timerInit(void);
|
|
void initTelemetry(serialPorts_t *serialPorts);
|
|
void serialInit(serialConfig_t *initialSerialConfig);
|
|
failsafe_t* failsafeInit(rxConfig_t *intialRxConfig);
|
|
void pwmInit(drv_pwm_config_t *init, failsafe_t *initialFailsafe);
|
|
void rxInit(rxConfig_t *rxConfig, failsafe_t *failsafe);
|
|
void buzzerInit(failsafe_t *initialFailsafe);
|
|
void gpsInit(uint8_t baudrateIndex, uint8_t initialGpsProvider, gpsProfile_t *initialGpsProfile, pidProfile_t *pidProfile);
|
|
void sensorsAutodetect(sensorAlignmentConfig_t *sensorAlignmentConfig, uint16_t gyroLpf, uint8_t accHardwareToUse, int16_t magDeclinationFromConfig);
|
|
void imuInit(void);
|
|
|
|
void loop(void);
|
|
|
|
int main(void)
|
|
{
|
|
uint8_t i;
|
|
drv_pwm_config_t pwm_params;
|
|
drv_adc_config_t adc_params;
|
|
#ifdef SOFTSERIAL_LOOPBACK
|
|
serialPort_t* loopbackPort1 = NULL;
|
|
serialPort_t* loopbackPort2 = NULL;
|
|
#endif
|
|
systemInit(masterConfig.emf_avoidance);
|
|
initPrintfSupport();
|
|
|
|
ensureEEPROMContainsValidData();
|
|
readEEPROM();
|
|
|
|
// configure power ADC
|
|
if (masterConfig.power_adc_channel > 0 && (masterConfig.power_adc_channel == 1 || masterConfig.power_adc_channel == 9))
|
|
adc_params.powerAdcChannel = masterConfig.power_adc_channel;
|
|
else {
|
|
adc_params.powerAdcChannel = 0;
|
|
masterConfig.power_adc_channel = 0;
|
|
}
|
|
|
|
adcInit(&adc_params);
|
|
initBoardAlignment(&masterConfig.boardAlignment);
|
|
|
|
// We have these sensors; SENSORS_SET defined in board.h depending on hardware platform
|
|
sensorsSet(SENSORS_SET);
|
|
|
|
mixerInit(masterConfig.mixerConfiguration, masterConfig.customMixer);
|
|
// when using airplane/wing mixer, servo/motor outputs are remapped
|
|
if (masterConfig.mixerConfiguration == MULTITYPE_AIRPLANE || masterConfig.mixerConfiguration == MULTITYPE_FLYING_WING)
|
|
pwm_params.airplane = true;
|
|
else
|
|
pwm_params.airplane = false;
|
|
pwm_params.useUART = feature(FEATURE_GPS) || feature(FEATURE_SERIALRX); // serial rx support uses UART too
|
|
pwm_params.useSoftSerial = canSoftwareSerialBeUsed();
|
|
pwm_params.usePPM = feature(FEATURE_PPM);
|
|
pwm_params.enableInput = !feature(FEATURE_SERIALRX); // disable inputs if using spektrum
|
|
pwm_params.useServos = isMixerUsingServos();
|
|
pwm_params.extraServos = currentProfile.gimbalConfig.gimbal_flags & GIMBAL_FORWARDAUX;
|
|
pwm_params.motorPwmRate = masterConfig.motor_pwm_rate;
|
|
pwm_params.servoPwmRate = masterConfig.servo_pwm_rate;
|
|
pwm_params.idlePulse = PULSE_1MS; // standard PWM for brushless ESC (default, overridden below)
|
|
if (feature(FEATURE_3D))
|
|
pwm_params.idlePulse = masterConfig.flight3DConfig.neutral3d;
|
|
if (pwm_params.motorPwmRate > 500)
|
|
pwm_params.idlePulse = 0; // brushed motors
|
|
pwm_params.servoCenterPulse = masterConfig.rxConfig.midrc;
|
|
pwm_params.failsafeThreshold = currentProfile.failsafeConfig.failsafe_detect_threshold;
|
|
|
|
switch (masterConfig.power_adc_channel) {
|
|
case 1:
|
|
pwm_params.adcChannel = PWM2;
|
|
break;
|
|
case 9:
|
|
pwm_params.adcChannel = PWM8;
|
|
break;
|
|
default:
|
|
pwm_params.adcChannel = 0;
|
|
break;
|
|
}
|
|
|
|
failsafe = failsafeInit(&masterConfig.rxConfig);
|
|
buzzerInit(failsafe);
|
|
timerInit();
|
|
pwmInit(&pwm_params, failsafe);
|
|
|
|
rxInit(&masterConfig.rxConfig, failsafe);
|
|
|
|
if (feature(FEATURE_GPS) && !feature(FEATURE_SERIALRX)) {
|
|
gpsInit(
|
|
masterConfig.gps_baudrate,
|
|
masterConfig.gps_type,
|
|
¤tProfile.gpsProfile,
|
|
¤tProfile.pidProfile
|
|
);
|
|
}
|
|
|
|
#ifdef SONAR
|
|
// sonar stuff only works with PPM
|
|
if (feature(FEATURE_PPM)) {
|
|
if (feature(FEATURE_SONAR))
|
|
Sonar_init();
|
|
}
|
|
#endif
|
|
|
|
LED1_ON;
|
|
LED0_OFF;
|
|
for (i = 0; i < 10; i++) {
|
|
LED1_TOGGLE;
|
|
LED0_TOGGLE;
|
|
delay(25);
|
|
BEEP_ON;
|
|
delay(25);
|
|
BEEP_OFF;
|
|
}
|
|
LED0_OFF;
|
|
LED1_OFF;
|
|
|
|
// drop out any sensors that don't seem to work, init all the others. halt if gyro is dead.
|
|
sensorsAutodetect(&masterConfig.sensorAlignmentConfig, masterConfig.gyro_lpf, masterConfig.acc_hardware, currentProfile.mag_declination);
|
|
imuInit(); // Mag is initialized inside imuInit
|
|
|
|
// Check battery type/voltage
|
|
if (feature(FEATURE_VBAT))
|
|
batteryInit(&masterConfig.batteryConfig);
|
|
|
|
serialInit(&masterConfig.serialConfig);
|
|
|
|
#ifndef FY90Q
|
|
if (canSoftwareSerialBeUsed()) {
|
|
//mcfg.softserial_baudrate = 19200; // Uncomment to override config value
|
|
|
|
setupSoftSerialPrimary(masterConfig.serialConfig.softserial_baudrate, masterConfig.serialConfig.softserial_1_inverted);
|
|
setupSoftSerialSecondary(masterConfig.serialConfig.softserial_2_inverted);
|
|
|
|
#ifdef SOFTSERIAL_LOOPBACK
|
|
loopbackPort1 = (serialPort_t*)&(softSerialPorts[0]);
|
|
serialPrint(loopbackPort1, "SOFTSERIAL 1 - LOOPBACK ENABLED\r\n");
|
|
|
|
loopbackPort2 = (serialPort_t*)&(softSerialPorts[1]);
|
|
serialPrint(loopbackPort2, "SOFTSERIAL 2 - LOOPBACK ENABLED\r\n");
|
|
#endif
|
|
//core.mainport = (serialPort_t*)&(softSerialPorts[0]); // Uncomment to switch the main port to use softserial.
|
|
}
|
|
#endif
|
|
|
|
if (feature(FEATURE_TELEMETRY))
|
|
initTelemetry(&serialPorts);
|
|
|
|
previousTime = micros();
|
|
|
|
if (masterConfig.mixerConfiguration == MULTITYPE_GIMBAL) {
|
|
accSetCalibrationCycles(CALIBRATING_ACC_CYCLES);
|
|
}
|
|
gyroSetCalibrationCycles(CALIBRATING_GYRO_CYCLES);
|
|
#ifdef BARO
|
|
baroSetCalibrationCycles(CALIBRATING_BARO_CYCLES);
|
|
#endif
|
|
|
|
f.SMALL_ANGLE = 1;
|
|
|
|
// loopy
|
|
while (1) {
|
|
loop();
|
|
#ifdef SOFTSERIAL_LOOPBACK
|
|
if (loopbackPort1) {
|
|
while (serialTotalBytesWaiting(loopbackPort1)) {
|
|
uint8_t b = serialRead(loopbackPort1);
|
|
serialWrite(loopbackPort1, b);
|
|
//serialWrite(core.mainport, 0x01);
|
|
//serialWrite(core.mainport, b);
|
|
};
|
|
}
|
|
|
|
if (loopbackPort2) {
|
|
while (serialTotalBytesWaiting(loopbackPort2)) {
|
|
#ifndef OLIMEXINO // PB0/D27 and PB1/D28 internally connected so this would result in a continuous stream of data
|
|
serialRead(loopbackPort2);
|
|
#else
|
|
uint8_t b = serialRead(loopbackPort2);
|
|
serialWrite(loopbackPort2, b);
|
|
//serialWrite(core.mainport, 0x02);
|
|
//serialWrite(core.mainport, b);
|
|
#endif // OLIMEXINO
|
|
};
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void HardFault_Handler(void)
|
|
{
|
|
// fall out of the sky
|
|
writeAllMotors(masterConfig.escAndServoConfig.mincommand);
|
|
while (1);
|
|
}
|