diff --git a/baseflight.uvopt b/baseflight.uvopt index 86e2437e6..ba1c30d5e 100755 --- a/baseflight.uvopt +++ b/baseflight.uvopt @@ -134,7 +134,7 @@ 0 DLGTARM - (1010=333,106,699,649,0)(1007=-1,-1,-1,-1,0)(1008=90,117,456,339,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(180=-1,-1,-1,-1,0)(120=-1,-1,-1,-1,0)(121=-1,-1,-1,-1,0)(122=-1,-1,-1,-1,0)(123=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=582,118,1166,798,0)(131=549,135,1133,815,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=791,309,1258,816,0)(230=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=570,175,1163,795,0)(151=-1,-1,-1,-1,0) + (1010=333,106,699,649,0)(1007=-1,-1,-1,-1,0)(1008=90,117,456,339,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(180=-1,-1,-1,-1,0)(120=-1,-1,-1,-1,0)(121=-1,-1,-1,-1,0)(122=-1,-1,-1,-1,0)(123=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=1289,156,1873,836,1)(131=549,135,1133,815,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=791,309,1258,816,0)(230=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=570,175,1163,795,0)(151=-1,-1,-1,-1,0) 0 @@ -157,6 +157,38 @@ -UV0168AVR -O206 -S8 -C0 -N00("ARM CoreSight SW-DP") -D00(1BA01477) -L00(0) -TO18 -TC72000000 -TP21 -TDS803D -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO11 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128 -FS08000000 -FL010000 + + + 0 + 0 + 361 + 1 +
134245422
+ 0 + 0 + 0 + 0 + 1 + F:\rc\freeflight\projects\baseflight\src\drv_pwm.c + + +
+ + 1 + 0 + 406 + 1 +
134245620
+ 0 + 0 + 0 + 0 + 1 + + + \\baseflight\src/drv_pwm.c\406 +
+
0 @@ -403,6 +435,21 @@ 0 0 + 361 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + F:\rc\freeflight\projects\baseflight\src\drv_pwm.c + + +
+ + 1 + 0 71 1
134232596
@@ -753,10 +800,10 @@ 1 0 0 - 0 + 17 0 - 1 - 1 + 336 + 349 0 .\src\cli.c cli.c @@ -767,10 +814,10 @@ 1 0 0 - 0 + 19 0 - 125 - 125 + 79 + 79 0 .\src\config.c config.c @@ -781,10 +828,10 @@ 1 0 0 - 104 + 1 0 - 114 - 135 + 1 + 24 0 .\src\imu.c imu.c @@ -797,8 +844,8 @@ 0 0 0 - 24 - 37 + 0 + 0 0 .\src\main.c main.c @@ -809,10 +856,10 @@ 1 0 0 - 61 + 0 0 - 194 - 194 + 187 + 211 0 .\src\mixer.c mixer.c @@ -823,10 +870,10 @@ 1 0 0 - 19 + 0 0 - 199 - 219 + 1 + 12 0 .\src\mw.c mw.c @@ -837,10 +884,10 @@ 1 0 0 - 17 + 26 0 - 23 - 26 + 139 + 152 0 .\src\sensors.c sensors.c @@ -851,10 +898,10 @@ 1 0 0 - 31 + 25 0 - 0 - 0 + 460 + 476 0 .\src\serial.c serial.c @@ -865,10 +912,10 @@ 5 0 0 - 0 + 13 0 - 55 - 66 + 1 + 1 0 .\src\board.h board.h @@ -879,10 +926,10 @@ 5 0 0 - 19 + 0 0 - 59 - 80 + 215 + 237 0 .\src\mw.h mw.h @@ -895,8 +942,8 @@ 0 0 0 - 0 - 0 + 169 + 209 0 .\src\gps.c gps.c @@ -907,10 +954,10 @@ 1 0 0 - 8 + 0 0 - 60 - 81 + 0 + 0 0 .\src\spektrum.c spektrum.c @@ -944,8 +991,8 @@ 0 0 0 - 0 - 0 + 43 + 73 0 .\src\drv_adxl345.c drv_adxl345.c @@ -958,8 +1005,8 @@ 0 15 0 - 1 - 19 + 0 + 0 0 .\src\drv_bmp085.c drv_bmp085.c @@ -986,8 +1033,8 @@ 0 0 0 - 132 - 150 + 0 + 0 0 .\src\drv_i2c.c drv_i2c.c @@ -1012,10 +1059,10 @@ 1 0 0 - 36 + 18 0 - 362 - 362 + 0 + 0 0 .\src\drv_pwm.c drv_pwm.c @@ -1026,10 +1073,10 @@ 1 0 0 - 0 + 15 0 - 38 - 50 + 0 + 0 0 .\src\drv_system.c drv_system.c @@ -1040,7 +1087,7 @@ 1 0 0 - 0 + 24 0 0 0 @@ -1068,10 +1115,10 @@ 1 0 0 - 0 + 26 0 147 - 168 + 167 0 .\src\drv_mpu6050.c drv_mpu6050.c @@ -1084,8 +1131,8 @@ 0 0 0 - 124 - 145 + 0 + 0 0 .\src\drv_adc_fy90q.c drv_adc_fy90q.c @@ -1098,8 +1145,8 @@ 0 0 0 - 176 - 176 + 0 + 0 0 .\src\drv_pwm_fy90q.c drv_pwm_fy90q.c @@ -1131,7 +1178,7 @@ 1 0 0 - 0 + 35 0 0 0 @@ -1161,8 +1208,8 @@ 0 19 0 - 656 - 656 + 0 + 0 0 .\lib\STM32F10x_StdPeriph_Driver\src\stm32f10x_adc.c stm32f10x_adc.c @@ -1287,8 +1334,8 @@ 0 0 0 - 146 - 166 + 0 + 0 0 .\src\baseflight_startups\startup_stm32f10x_md.s startup_stm32f10x_md.s @@ -1301,8 +1348,8 @@ 0 0 0 - 125 - 133 + 0 + 0 0 .\src\baseflight_startups\startup_stm32f10x_md_fy90q.s startup_stm32f10x_md_fy90q.s diff --git a/src/buzzer.c b/src/buzzer.c new file mode 100644 index 000000000..5e884d972 --- /dev/null +++ b/src/buzzer.c @@ -0,0 +1,115 @@ +#include "board.h" +#include "mw.h" + +void buzzer(uint8_t warn_vbat) +{ + static uint16_t ontime, offtime, beepcount, repeat, repeatcounter; + static uint32_t buzzerLastToggleTime; + static uint8_t buzzerIsOn = 0, activateBuzzer, beeperOnBox, i, last_rcOptions[CHECKBOXITEMS], warn_noGPSfix = 0, warn_failsafe = 0; + + //===================== Beeps for changing rcOptions ===================== +#if defined(RCOPTIONSBEEP) + if (last_rcOptions[i] != rcOptions[i]) { + toggleBeep = 1; + } + last_rcOptions[i] = rcOptions[i]; + i++; + if (i >= CHECKBOXITEMS) + i = 0; +#endif + //===================== BeeperOn via rcOptions ===================== + if (rcOptions[BOXBEEPERON]) { // unconditional beeper on via AUXn switch + beeperOnBox = 1; + } else { + beeperOnBox = 0; + } + //===================== Beeps for failsafe ===================== +#if defined(FAILSAFE) + if (failsafeCnt > (5 * FAILSAVE_DELAY) && armed == 1) { + warn_failsafe = 1; //set failsafe warning level to 1 while landing + if (failsafeCnt > 5 * (FAILSAVE_DELAY + FAILSAVE_OFF_DELAY)) + warn_failsafe = 2; //start "find me" signal after landing + } + if (failsafeCnt > (5 * FAILSAVE_DELAY) && armed == 0) + warn_failsafe = 2; // tx turned off while motors are off: start "find me" signal + if (failsafeCnt == 0) + warn_failsafe = 0; // turn off alarm if TX is okay +#endif + //===================== GPS fix notification handling ===================== + if (sensors(SENSOR_GPS)) { + if ((GPSModeHome || GPSModeHold) && !GPS_fix) { //if no fix and gps funtion is activated: do warning beeps. + warn_noGPSfix = 1; + } else { + warn_noGPSfix = 0; + } + } + //===================== Main Handling Block ===================== + repeat = 1; // set repeat to default + ontime = 100; // set offtime to default + + //the order of the below is the priority from high to low, the last entry has the lowest priority, only one option can be active at the same time + if (warn_failsafe == 2) { + activateBuzzer = 1; + offtime = 2000; + ontime = 300; + repeat = 1; + } //failsafe "find me" signal + else if (warn_failsafe == 1) { + activateBuzzer = 1; + offtime = 50; + } //failsafe landing active + else if (warn_noGPSfix == 1) { + activateBuzzer = 1; + offtime = 10; + } else if (beeperOnBox == 1) { + activateBuzzer = 1; + offtime = 50; + } //beeperon + else if (warn_vbat == 4) { + activateBuzzer = 1; + offtime = 500; + repeat = 3; + } else if (warn_vbat == 2) { + activateBuzzer = 1; + offtime = 1000; + repeat = 2; + } else if (warn_vbat == 1) { + activateBuzzer = 1; + offtime = 2000; + } else if (toggleBeep > 0) { + activateBuzzer = 1; + ontime = 50; + offtime = 50; + } //fast confirmation beep + else { + activateBuzzer = 0; + } + + if (activateBuzzer) { + if (repeatcounter > 1 && !buzzerIsOn && (millis() >= (buzzerLastToggleTime + 80))) { // if the buzzer is off and there is a short pause neccessary (multipe buzzes) + buzzerIsOn = 1; + BEEP_ON; + buzzerLastToggleTime = millis(); // save the time the buzer turned on + repeatcounter--; + } else if (!buzzerIsOn && (millis() >= (buzzerLastToggleTime + offtime))) { // Buzzer is off and long pause time is up -> turn it on + buzzerIsOn = 1; + BEEP_ON; + buzzerLastToggleTime = millis(); // save the time the buzer turned on + repeatcounter = repeat; //set the amount of repeats + } else if (buzzerIsOn && (millis() >= buzzerLastToggleTime + ontime)) { //Buzzer is on and time is up -> turn it off + buzzerIsOn = 0; + BEEP_OFF; + buzzerLastToggleTime = millis(); // save the time the buzer turned on + if (toggleBeep > 0) + beepcount++; // only increment if confirmation beep, the rest is endless while the condition is given + } + if (beepcount >= toggleBeep) { //confirmation flag is 0,1 or 2 + beepcount = 0; //reset the counter for the next time + toggleBeep = 0; //reset the flag after all beeping is done + } + } else { //no beeping neccessary:reset everything (just in case) + beepcount = 0; //reset the counter for the next time + BEEP_OFF; + buzzerIsOn = 0; + } +} diff --git a/src/cli.c b/src/cli.c index 2b669ba5c..55e8f9715 100644 --- a/src/cli.c +++ b/src/cli.c @@ -346,7 +346,7 @@ static void cliMixer(char *cmdline) static void cliSave(char *cmdline) { uartPrint("Saving..."); - writeParams(); + writeParams(0); uartPrint("\r\nRebooting..."); delay(10); systemReset(false); diff --git a/src/config.c b/src/config.c index 11c312df7..6a29e3536 100755 --- a/src/config.c +++ b/src/config.c @@ -13,7 +13,7 @@ config_t cfg; const char rcChannelLetters[] = "AERT1234"; static uint32_t enabledSensors = 0; -static uint8_t checkNewConf = 13; +uint8_t checkNewConf = 14; void parseRcChannels(const char *input) { @@ -33,15 +33,26 @@ void readEEPROM(void) // Read flash memcpy(&cfg, (char *)FLASH_WRITE_ADDR, sizeof(config_t)); - for (i = 0; i < 7; i++) - lookupRX[i] = (2500 + cfg.rcExpo8 * (i * i - 25)) * i * (int32_t) cfg.rcRate8 / 1250; + for(i = 0; i < 6; i++) + lookupPitchRollRC[i] = (2500 + cfg.rcExpo8 * (i * i - 25)) * i * (int32_t)cfg.rcRate8 / 2500; + + for(i = 0; i < 11; i++) { + int16_t tmp = 10 * i - cfg.thrMid8; + uint8_t y = 1; + if (tmp > 0) + y = 100 - cfg.thrMid8; + if (tmp < 0) + y = cfg.thrMid8; + lookupThrottleRC[i] = 10 * cfg.thrMid8 + tmp * (100 - cfg.thrExpo8 + (int32_t)cfg.thrExpo8 * (tmp * tmp) / (y * y) ) / 10; // [0;1000] + lookupThrottleRC[i] = cfg.minthrottle + (int32_t)(cfg.maxthrottle - cfg.minthrottle)* lookupThrottleRC[i] / 1000; // [0;1000] -> [MINTHROTTLE;MAXTHROTTLE] + } cfg.wing_left_mid = constrain(cfg.wing_left_mid, WING_LEFT_MIN, WING_LEFT_MAX); //LEFT cfg.wing_right_mid = constrain(cfg.wing_right_mid, WING_RIGHT_MIN, WING_RIGHT_MAX); //RIGHT cfg.tri_yaw_middle = constrain(cfg.tri_yaw_middle, TRI_YAW_CONSTRAINT_MIN, TRI_YAW_CONSTRAINT_MAX); //REAR } -void writeParams(void) +void writeParams(uint8_t b) { FLASH_Status status; uint32_t i; @@ -61,7 +72,8 @@ void writeParams(void) FLASH_Lock(); readEEPROM(); - blinkLED(15, 20, 1); + if (b) + blinkLED(15, 20, 1); } void checkFirstTime(bool reset) @@ -86,7 +98,7 @@ void checkFirstTime(bool reset) cfg.I8[PITCH] = 30; cfg.D8[PITCH] = 23; cfg.P8[YAW] = 85; - cfg.I8[YAW] = 0; + cfg.I8[YAW] = 45; cfg.D8[YAW] = 0; cfg.P8[PIDALT] = 16; cfg.I8[PIDALT] = 15; @@ -97,25 +109,25 @@ void checkFirstTime(bool reset) cfg.P8[PIDVEL] = 0; cfg.I8[PIDVEL] = 0; cfg.D8[PIDVEL] = 0; - cfg.P8[PIDLEVEL] = 90; - cfg.I8[PIDLEVEL] = 45; + cfg.P8[PIDLEVEL] = 70; + cfg.I8[PIDLEVEL] = 10; cfg.D8[PIDLEVEL] = 100; cfg.P8[PIDMAG] = 40; - cfg.rcRate8 = 45; // = 0.9 in GUI + cfg.rcRate8 = 90; cfg.rcExpo8 = 65; cfg.rollPitchRate = 0; cfg.yawRate = 0; cfg.dynThrPID = 0; - for (i = 0; i < CHECKBOXITEMS; i++) { - cfg.activate1[i] = 0; - cfg.activate2[i] = 0; - } + cfg.thrMid8 = 50; + cfg.thrExpo8 = 0; + for (i = 0; i < CHECKBOXITEMS; i++) + cfg.activate[i] = 0; cfg.accTrim[0] = 0; cfg.accTrim[1] = 0; cfg.accZero[0] = 0; cfg.accZero[1] = 0; cfg.accZero[2] = 0; - cfg.acc_lpf_factor = 4; + cfg.acc_lpf_factor = 100; cfg.gyro_lpf = 42; cfg.gyro_smoothing_factor = 0x00141403; // default factors of 20, 20, 3 for R/P/Y cfg.vbatscale = 110; @@ -163,7 +175,7 @@ void checkFirstTime(bool reset) // serial(uart1) baudrate cfg.serial_baudrate = 115200; - writeParams(); + writeParams(0); } bool sensors(uint32_t mask) diff --git a/src/drv_adxl345.c b/src/drv_adxl345.c index 8ccfa6158..7d6245d04 100755 --- a/src/drv_adxl345.c +++ b/src/drv_adxl345.c @@ -29,6 +29,7 @@ #define ADXL345_RANGE_16G 0x03 #define ADXL345_FIFO_STREAM 0x80 +extern uint16_t acc_1G; static void adxl345Init(void); static void adxl345Read(int16_t *accelData); @@ -67,6 +68,7 @@ static void adxl345Init(void) i2cWrite(ADXL345_ADDRESS, ADXL345_DATA_FORMAT, ADXL345_FULL_RANGE | ADXL345_RANGE_8G); i2cWrite(ADXL345_ADDRESS, ADXL345_BW_RATE, ADXL345_RATE_100); } + acc_1G = 265; // 3.3V operation } uint8_t acc_samples = 0; diff --git a/src/drv_ledring.c b/src/drv_ledring.c index 6d9f56e4c..e7e1e552e 100644 --- a/src/drv_ledring.c +++ b/src/drv_ledring.c @@ -21,25 +21,25 @@ void ledringState(void) static uint8_t state; if (state == 0) { - b[0] = 'z'; - b[1] = (180 - heading) / 2; // 1 unit = 2 degrees; + b[0] = 'z'; + b[1] = (180 - heading) / 2; // 1 unit = 2 degrees; i2cWriteBuffer(LED_RING_ADDRESS, 0xFF, 2, b); - state = 1; + state = 1; } else if (state == 1) { - b[0] = 'y'; - b[1] = constrain(angle[ROLL] / 10 + 90, 0, 180); - b[2] = constrain(angle[PITCH] / 10 + 90, 0, 180); + b[0] = 'y'; + b[1] = constrain(angle[ROLL] / 10 + 90, 0, 180); + b[2] = constrain(angle[PITCH] / 10 + 90, 0, 180); i2cWriteBuffer(LED_RING_ADDRESS, 0xFF, 3, b); - state = 2; + state = 2; } else if (state == 2) { - b[0] = 'd'; // all unicolor GREEN - b[1] = 1; - if (armed) - b[2] = 1; - else - b[2] = 0; + b[0] = 'd'; // all unicolor GREEN + b[1] = 1; + if (armed) + b[2] = 1; + else + b[2] = 0; i2cWriteBuffer(LED_RING_ADDRESS, 0xFF, 3, b); - state = 0; + state = 0; } } diff --git a/src/gps.c b/src/gps.c index 7d78cc920..50599fb34 100644 --- a/src/gps.c +++ b/src/gps.c @@ -42,6 +42,12 @@ static void GPS_NewData(uint16_t c) } } +void GPS_reset_home_position(void) +{ + GPS_latitude_home = GPS_latitude; + GPS_longitude_home = GPS_longitude; +} + /* this is an equirectangular approximation to calculate distance and bearing between 2 GPS points (lat/long) it's much more faster than an exact calculation the error is neglectible for few kilometers assuming a constant R for earth diff --git a/src/imu.c b/src/imu.c index f8e1a1ab0..e2ad6dbde 100755 --- a/src/imu.c +++ b/src/imu.c @@ -4,6 +4,7 @@ int16_t gyroADC[3], accADC[3], accSmooth[3], magADC[3]; int16_t acc_25deg = 0; int32_t BaroAlt; +int16_t sonarAlt; //to think about the unit int32_t EstAlt; // in cm int16_t BaroPID = 0; int32_t AltHold; @@ -175,7 +176,7 @@ static void getEstimatedAttitude(void) #if defined(MG_LPF_FACTOR) static int16_t mgSmooth[3]; #endif - static float accTemp[3]; // projection of smoothed and normalized magnetic vector on x/y/z axis, as measured by magnetometer + static float accLPF[3]; static uint32_t previousT; uint32_t currentT = micros(); float scale, deltaGyroAngle[3]; @@ -187,10 +188,8 @@ static void getEstimatedAttitude(void) for (axis = 0; axis < 3; axis++) { deltaGyroAngle[axis] = gyroADC[axis] * scale; if (cfg.acc_lpf_factor > 0) { - accTemp[axis] = accTemp[axis] * (1.0f - (1.0f / cfg.acc_lpf_factor)) + accADC[axis] * (1.0f / cfg.acc_lpf_factor); - accSmooth[axis] = roundf(accTemp[axis]); - // accTemp[axis] = (accTemp[axis] - (accTemp[axis] >> cfg.acc_lpf_factor)) + accADC[axis]; - // accSmooth[axis] = accTemp[axis] >> cfg.acc_lpf_factor; + accLPF[axis] = accLPF[axis] * (1.0f - (1.0f / cfg.acc_lpf_factor)) + accADC[axis] * (1.0f / cfg.acc_lpf_factor); + accSmooth[axis] = accLPF[axis]; } else { accSmooth[axis] = accADC[axis]; } @@ -221,10 +220,8 @@ static void getEstimatedAttitude(void) // If accel magnitude >1.4G or <0.6G and ACC vector outside of the limit range => we neutralize the effect of accelerometers in the angle estimation. // To do that, we just skip filter, as EstV already rotated by Gyro if ((36 < accMag && accMag < 196) || smallAngle25) { - for (axis = 0; axis < 3; axis++) { - // int16_t acc = accSmooth[axis]; - EstG.A[axis] = (EstG.A[axis] * GYR_CMPF_FACTOR + accTemp[axis]) * INV_GYR_CMPF_FACTOR; - } + for (axis = 0; axis < 3; axis++) + EstG.A[axis] = (EstG.A[axis] * GYR_CMPF_FACTOR + accSmooth[axis]) * INV_GYR_CMPF_FACTOR; } if (sensors(SENSOR_MAG)) { diff --git a/src/mixer.c b/src/mixer.c index 36263e718..016384ccb 100755 --- a/src/mixer.c +++ b/src/mixer.c @@ -205,10 +205,10 @@ void mixTable(void) break; case MULTITYPE_VTAIL4: - motor[0] = PIDMIX(+0, +1, -1 / 2); //REAR_R - motor[1] = PIDMIX(-1, -1, +2 / 10); //FRONT_R - motor[2] = PIDMIX(+0, +1, +1 / 2); //REAR_L - motor[3] = PIDMIX(+1, -1, -2 / 10); //FRONT_L + motor[0] = PIDMIX(+0, +1, -1 / 2); //REAR_R + motor[1] = PIDMIX(-1, -1, +0); //FRONT_R + motor[2] = PIDMIX(+0, +1, +1 / 2); //REAR_L + motor[3] = PIDMIX(+1, -1, -0); //FRONT_L break; case MULTITYPE_GIMBAL: diff --git a/src/mw.c b/src/mw.c index 4d1762a74..d80e35650 100755 --- a/src/mw.c +++ b/src/mw.c @@ -8,6 +8,7 @@ int16_t debug1, debug2, debug3, debug4; uint8_t buzzerState = 0; +uint8_t toggleBeep = 0; uint32_t currentTime = 0; uint32_t previousTime = 0; uint16_t cycleTime = 0; // this is the number in micro second to achieve a full loop, it can differ a little and is taken into account in the PID loop @@ -16,6 +17,7 @@ uint8_t GPSModeHold = 0; // if GPS PH is activated uint8_t headFreeMode = 0; // if head free mode is a activated uint8_t passThruMode = 0; // if passthrough mode is activated int16_t headFreeModeHold; + int16_t annex650_overrun_count = 0; uint8_t armed = 0; uint8_t vbat; // battery voltage in 0.1V steps @@ -24,7 +26,8 @@ volatile int16_t failsafeCnt = 0; int16_t failsafeEvents = 0; int16_t rcData[8] = { 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500 }; // interval [1000;2000] int16_t rcCommand[4]; // interval [1000;2000] for THROTTLE and [-500;+500] for ROLL/PITCH/YAW -int16_t lookupRX[7]; // lookup table for expo & RC rate +int16_t lookupPitchRollRC[6]; // lookup table for expo & RC rate PITCH+ROLL +int16_t lookupThrottleRC[11]; // lookup table for expo & mid THROTTLE rcReadRawDataPtr rcReadRawFunc = NULL; // receive data from default (pwm/ppm) or additional (spek/sbus/?? receiver drivers) uint8_t dynP8[3], dynI8[3], dynD8[3]; @@ -50,7 +53,8 @@ uint16_t GPS_distanceToHome, GPS_distanceToHold; // distance to home or h int16_t GPS_directionToHome, GPS_directionToHold; // direction to home or hol point in degrees uint16_t GPS_altitude, GPS_speed; // altitude in 0.1m and speed in 0.1m/s - Added by Mis uint8_t GPS_update = 0; // it's a binary toogle to distinct a GPS position update -int16_t GPS_angle[2]; // it's the angles that must be applied for GPS correction +int16_t GPS_angle[2] = { 0, 0 }; // it's the angles that must be applied for GPS correction +uint16_t GPS_ground_course = 0; // degrees*10 //Automatic ACC Offset Calibration // ********************** @@ -79,10 +83,13 @@ void blinkLED(uint8_t num, uint8_t wait, uint8_t repeat) } } +#define BREAKPOINT 1500 + // this code is executed at each loop and won't interfere with control loop if it lasts less than 650 microseconds void annexCode(void) { static uint32_t buzzerTime, calibratedAccTime; + uint16_t tmp,tmp2; static uint8_t vbatTimer = 0; static uint8_t buzzerFreq; //delay between buzzer ring uint8_t axis, prop1, prop2; @@ -92,18 +99,19 @@ void annexCode(void) uint8_t i; // PITCH & ROLL only dynamic PID adjustemnt, depending on throttle value - if (rcData[THROTTLE] < 1500) { + if (rcData[THROTTLE] < BREAKPOINT) { prop2 = 100; - } else if (rcData[THROTTLE] < 2000) { - prop2 = 100 - (uint16_t) cfg.dynThrPID * (rcData[THROTTLE] - 1500) / 500; } else { - prop2 = 100 - cfg.dynThrPID; + if (rcData[THROTTLE] < 2000) { + prop2 = 100 - (uint16_t)cfg.dynThrPID * (rcData[THROTTLE] - BREAKPOINT) / (2000 - BREAKPOINT); + } else { + prop2 = 100 - cfg.dynThrPID; + } } for (axis = 0; axis < 3; axis++) { - uint16_t tmp = min(abs(rcData[axis] - cfg.midrc), 500); + tmp = min(abs(rcData[axis] - cfg.midrc), 500); if (axis != 2) { // ROLL & PITCH - uint16_t tmp2; if (cfg.deadband) { if (tmp > cfg.deadband) { tmp -= cfg.deadband; @@ -111,8 +119,9 @@ void annexCode(void) tmp = 0; } } + tmp2 = tmp / 100; - rcCommand[axis] = lookupRX[tmp2] + (tmp - tmp2 * 100) * (lookupRX[tmp2 + 1] - lookupRX[tmp2]) / 100; + rcCommand[axis] = lookupPitchRollRC[tmp2] + (tmp - tmp2 * 100) * (lookupPitchRollRC[tmp2 + 1] - lookupPitchRollRC[tmp2]) / 100; prop1 = 100 - (uint16_t) cfg.rollPitchRate * tmp / 500; prop1 = (uint16_t)prop1 * prop2 / 100; } else { // YAW @@ -131,7 +140,12 @@ void annexCode(void) if (rcData[axis] < cfg.midrc) rcCommand[axis] = -rcCommand[axis]; } - rcCommand[THROTTLE] = cfg.minthrottle + (int32_t)(cfg.maxthrottle - cfg.minthrottle) * (rcData[THROTTLE] - cfg.mincheck) / (2000 - cfg.mincheck); + + tmp = constrain(rcData[THROTTLE], cfg.mincheck, 2000); + tmp = (uint32_t)(tmp - cfg.mincheck) * 1000 / (2000 - cfg.mincheck); // [MINCHECK;2000] -> [0;1000] + tmp2 = tmp / 100; + rcCommand[THROTTLE] = lookupThrottleRC[tmp2] + (tmp - tmp2 * 100) * (lookupThrottleRC[tmp2 + 1] - lookupThrottleRC[tmp2]) / 100; // [0;1000] -> expo -> [MINTHROTTLE;MAXTHROTTLE] + // rcCommand[THROTTLE] = cfg.minthrottle + (int32_t)(cfg.maxthrottle - cfg.minthrottle) * (rcData[THROTTLE] - cfg.mincheck) / (2000 - cfg.mincheck); if (headFreeMode) { float radDiff = (heading - headFreeModeHold) * M_PI / 180.0f; @@ -157,6 +171,8 @@ void annexCode(void) BEEP_OFF; } else buzzerFreq = 4; // low battery + +#if 0 if (buzzerFreq) { if (buzzerState && (currentTime > buzzerTime + 250000)) { buzzerState = 0; @@ -168,8 +184,11 @@ void annexCode(void) buzzerTime = currentTime; } } +#endif } + buzzer(buzzerFreq); // external buzzer routine that handles buzzer events globally now + if ((calibratingA > 0 && sensors(SENSOR_ACC)) || (calibratingG > 0)) { // Calibration phasis LED0_TOGGLE; } else { @@ -290,8 +309,11 @@ void loop(void) errorAngleI[PITCH] = 0; rcDelayCommand++; if (rcData[YAW] < cfg.mincheck && rcData[PITCH] < cfg.mincheck && armed == 0) { - if (rcDelayCommand == 20) + if (rcDelayCommand == 20) { calibratingG = 400; + if (feature(FEATURE_GPS)) + GPS_reset_home_position(); + } } else if (feature(FEATURE_INFLIGHT_ACC_CAL) && (armed == 0 && rcData[YAW] < cfg.mincheck && rcData[PITCH] > cfg.maxcheck && rcData[ROLL] > cfg.maxcheck)) { if (rcDelayCommand == 20) { if (AccInflightCalibrationMeasurementDone) { // trigger saving into eeprom after landing @@ -300,13 +322,13 @@ void loop(void) } else { AccInflightCalibrationArmed = !AccInflightCalibrationArmed; if (AccInflightCalibrationArmed) { - blinkLED(10, 1, 2); + toggleBeep = 2; } else { - blinkLED(10, 10, 3); + toggleBeep = 3; } } } - } else if ((cfg.activate1[BOXARM] > 0) || (cfg.activate2[BOXARM] > 0)) { + } else if (cfg.activate[BOXARM] > 0) { if (rcOptions[BOXARM] && okToArm) { armed = 1; headFreeModeHold = heading; @@ -334,28 +356,28 @@ void loop(void) rcDelayCommand++; } else if (rcData[PITCH] > cfg.maxcheck) { cfg.accTrim[PITCH] += 2; - writeParams(); + writeParams(1); #ifdef LEDRING if (feature(FEATURE_LED_RING)) ledringBlink(); #endif } else if (rcData[PITCH] < cfg.mincheck) { cfg.accTrim[PITCH] -= 2; - writeParams(); + writeParams(1); #ifdef LEDRING if (feature(FEATURE_LED_RING)) ledringBlink(); #endif } else if (rcData[ROLL] > cfg.maxcheck) { cfg.accTrim[ROLL] += 2; - writeParams(); + writeParams(1); #ifdef LEDRING if (feature(FEATURE_LED_RING)) ledringBlink(); #endif } else if (rcData[ROLL] < cfg.mincheck) { cfg.accTrim[ROLL] -= 2; - writeParams(); + writeParams(1); #ifdef LEDRING if (feature(FEATURE_LED_RING)) ledringBlink(); @@ -364,12 +386,6 @@ void loop(void) rcDelayCommand = 0; } } -#ifdef LOG_VALUES - if (cycleTime > cycleTimeMax) - cycleTimeMax = cycleTime; // remember highscore - if (cycleTime < cycleTimeMin) - cycleTimeMin = cycleTime; // remember lowscore -#endif if (feature(FEATURE_INFLIGHT_ACC_CAL)) { if (AccInflightCalibrationArmed && armed == 1 && rcData[THROTTLE] > cfg.mincheck && !rcOptions[BOXARM]) { // Copter is airborne and you are turning it off via boxarm : start measurement @@ -389,8 +405,11 @@ void loop(void) } for (i = 0; i < CHECKBOXITEMS; i++) { - rcOptions[i] = (((rcData[AUX1] < 1300) | (1300 < rcData[AUX1] && rcData[AUX1] < 1700) << 1 | (rcData[AUX1] > 1700) << 2 | (rcData[AUX2] < 1300) << 3 | (1300 < rcData[AUX2] && rcData[AUX2] < 1700) << 4 | (rcData[AUX2] > 1700) << 5) & cfg.activate1[i]) - || (((rcData[AUX3] < 1300) | (1300 < rcData[AUX3] && rcData[AUX3] < 1700) << 1 | (rcData[AUX3] > 1700) << 2 | (rcData[AUX4] < 1300) << 3 | (1300 < rcData[AUX4] && rcData[AUX4] < 1700) << 4 | (rcData[AUX4] > 1700) << 5) & cfg.activate2[i]); + rcOptions[i] = ( + ((rcData[AUX1] < 1300) | (1300 < rcData[AUX1] && rcData[AUX1] < 1700) <<1 | (rcData[AUX1] > 1700) << 2 + | (rcData[AUX2] < 1300) << 3 | (1300 < rcData[AUX2] && rcData[AUX2] < 1700) << 4 | (rcData[AUX2] > 1700) << 5 + | (rcData[AUX3] < 1300) << 6 | (1300 < rcData[AUX3] && rcData[AUX3] < 1700) << 7 | (rcData[AUX3] > 1700) << 8 + | (rcData[AUX4] < 1300) << 9 | (1300 < rcData[AUX4] && rcData[AUX4] < 1700) << 10| (rcData[AUX4] > 1700) << 11) & cfg.activate[i]) > 0; } // note: if FAILSAFE is disable, failsafeCnt > 5*FAILSAVE_DELAY is always false @@ -402,7 +421,7 @@ void loop(void) accMode = 1; } } else - accMode = 0; // modified by MIS for failsave support + accMode = 0; // failsave support if ((rcOptions[BOXARM]) == 0) okToArm = 1; @@ -467,32 +486,29 @@ void loop(void) passThruMode = 0; } else { // not in rc loop static int8_t taskOrder = 0; // never call all function in the same loop, to avoid high delay spikes - switch (taskOrder) { + switch (taskOrder++ % 4) { case 0: - taskOrder++; #ifdef MAG if (sensors(SENSOR_MAG)) Mag_getADC(); #endif break; case 1: - taskOrder++; #ifdef BARO if (sensors(SENSOR_BARO)) Baro_update(); #endif break; case 2: - taskOrder++; #ifdef BARO if (sensors(SENSOR_BARO)) getEstimatedAltitude(); #endif break; case 3: - taskOrder++; -#if 0 // GPS - not used as we read gps data in interrupt mode - GPS_NewData(); +#ifdef SONAR + Sonar_update(); + debug3 = sonarAlt; #endif break; default: diff --git a/src/mw.h b/src/mw.h index ee5b0e298..a725a2768 100755 --- a/src/mw.h +++ b/src/mw.h @@ -1,9 +1,5 @@ #pragma once -/* This option should be uncommented if ACC Z is accurate enough when motors are running*/ -/* should now be ok with BMA020 and BMA180 ACC */ -#define TRUSTED_ACCZ - /* Failsave settings - added by MIS Failsafe check pulse on THROTTLE channel. If the pulse is OFF (on only THROTTLE or on all channels) the failsafe procedure is initiated. After FAILSAVE_DELAY time of pulse absence, the level mode is on (if ACC or nunchuk is avaliable), PITCH, ROLL and YAW is centered @@ -43,14 +39,7 @@ /* for VBAT monitoring frequency */ #define VBATFREQ 6 // to read battery voltage - keep equal to PSENSORFREQ (6) unless you know what you are doing -// Moving Average Gyros by Magnetron1 (Michele Ardito) ########## beta -//#define MMGYRO // Active Moving Average Function for Gyros -//#define MMGYROVECTORLENGHT 10 // Lenght of Moving Average Vector -// Moving Average ServoGimbal Signal Output -//#define MMSERVOGIMBAL // Active Output Moving Average Function for Servos Gimbal -//#define MMSERVOGIMBALVECTORLENGHT 32 // Lenght of Moving Average Vector - -#define VERSION 20 +#define VERSION 200 // Syncronized with GUI. Only exception is mixer > 11, which is always returned as 11 during serialization. typedef enum MultiType @@ -128,6 +117,9 @@ typedef struct config_t { uint8_t rcRate8; uint8_t rcExpo8; + uint8_t thrMid8; + uint8_t thrExpo8; + uint8_t rollPitchRate; uint8_t yawRate; @@ -141,8 +133,7 @@ typedef struct config_t { uint16_t gyro_lpf; // mpuX050 LPF setting uint32_t gyro_smoothing_factor; // How much to smoothen with per axis (32bit value with Roll, Pitch, Yaw in bits 24, 16, 8 respectively - uint8_t activate1[CHECKBOXITEMS]; - uint8_t activate2[CHECKBOXITEMS]; + uint16_t activate[CHECKBOXITEMS]; // activate switches uint8_t vbatscale; // adjust this to match battery voltage to reported value uint8_t vbatmaxcellvoltage; // maximum voltage per cell, used for auto-detecting battery voltage in 0.1V units, default is 43 (4.3V) uint8_t vbatmincellvoltage; // minimum voltage per cell, this triggers battery out alarms, in 0.1V units, default is 33 (3.3V) @@ -211,6 +202,7 @@ extern int16_t heading; extern int16_t annex650_overrun_count; extern int32_t pressure; extern int32_t BaroAlt; +extern int16_t sonarAlt; extern int32_t EstAlt; extern int32_t AltHold; extern int16_t errorAltitudeI; @@ -240,7 +232,9 @@ extern uint8_t GPSModeHold; extern uint16_t GPS_altitude; extern uint16_t GPS_speed; // altitude in 0.1m and speed in 0.1m/s - Added by Mis extern uint8_t vbat; -extern int16_t lookupRX[7]; // lookup table for expo & RC rate +extern int16_t lookupPitchRollRC[6]; // lookup table for expo & RC rate PITCH+ROLL +extern int16_t lookupThrottleRC[11]; // lookup table for expo & mid THROTTLE +extern uint8_t toggleBeep; extern config_t cfg; extern sensor_t acc; @@ -280,7 +274,7 @@ void serialCom(void); // Config void parseRcChannels(const char *input); void readEEPROM(void); -void writeParams(void); +void writeParams(uint8_t b); void checkFirstTime(bool reset); bool sensors(uint32_t mask); void sensorsSet(uint32_t mask); @@ -301,3 +295,4 @@ void cliProcess(void); // gps void gpsInit(uint32_t baudrate); +void GPS_reset_home_position(void); diff --git a/src/sensors.c b/src/sensors.c index 8a8368677..6c781ab8c 100755 --- a/src/sensors.c +++ b/src/sensors.c @@ -5,7 +5,7 @@ uint8_t calibratedACC = 0; uint16_t calibratingA = 0; // the calibration is done is the main loop. Calibrating decreases at each cycle down to 0, then we enter in a normal mode. uint16_t calibratingG = 0; uint8_t calibratingM = 0; -uint16_t acc_1G = 256; // this is the 1G measured acceleration +uint16_t acc_1G = 256; // this is the 1G measured acceleration. int16_t heading, magHold; extern uint16_t InflightcalibratingA; @@ -116,7 +116,7 @@ static void ACC_Common(void) cfg.accZero[YAW] = a[YAW] / 400 - acc_1G; // for nunchuk 200=1G cfg.accTrim[ROLL] = 0; cfg.accTrim[PITCH] = 0; - writeParams(); // write accZero in EEPROM + writeParams(1); // write accZero in EEPROM } calibratingA--; } @@ -149,7 +149,7 @@ static void ACC_Common(void) if (InflightcalibratingA == 1) { AccInflightCalibrationActive = 0; AccInflightCalibrationMeasurementDone = 1; - blinkLED(10, 10, 2); //buzzer for indicatiing the start inflight + toggleBeep = 2; //buzzer for indicatiing the end of calibration // recover saved values to maintain current flight behavior until new values are transferred cfg.accZero[ROLL] = accZero_saved[ROLL]; cfg.accZero[PITCH] = accZero_saved[PITCH]; @@ -167,7 +167,7 @@ static void ACC_Common(void) cfg.accZero[YAW] = b[YAW] / 50 - acc_1G; // for nunchuk 200=1G cfg.accTrim[ROLL] = 0; cfg.accTrim[PITCH] = 0; - writeParams(); // write accZero in EEPROM + writeParams(1); // write accZero in EEPROM } } @@ -367,7 +367,7 @@ void Mag_getADC(void) tCal = 0; for (axis = 0; axis < 3; axis++) cfg.magZero[axis] = (magZeroTempMin[axis] + magZeroTempMax[axis]) / 2; - writeParams(); + writeParams(1); } } } diff --git a/src/serial.c b/src/serial.c index 64f90fa1c..38eb0d6fc 100755 --- a/src/serial.c +++ b/src/serial.c @@ -1,26 +1,361 @@ #include "board.h" #include "mw.h" -// signal that we're in cli mode -uint8_t cliMode = 0; +#define MSP_IDENT 100 //out message multitype + version +#define MSP_STATUS 101 //out message cycletime & errors_count & sensor present & box activation +#define MSP_RAW_IMU 102 //out message 9 DOF +#define MSP_SERVO 103 //out message 8 servos +#define MSP_MOTOR 104 //out message 8 motors +#define MSP_RC 105 //out message 8 rc chan +#define MSP_RAW_GPS 106 //out message fix, numsat, lat, lon, alt, speed +#define MSP_COMP_GPS 107 //out message distance home, direction home +#define MSP_ATTITUDE 108 //out message 2 angles 1 heading +#define MSP_ALTITUDE 109 //out message 1 altitude +#define MSP_BAT 110 //out message vbat, powermetersum +#define MSP_RC_TUNING 111 //out message rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID +#define MSP_PID 112 //out message up to 16 P I D (8 are used) +#define MSP_BOX 113 //out message up to 16 checkbox (11 are used) +#define MSP_MISC 114 //out message powermeter trig + 8 free for future use + +#define MSP_SET_RAW_RC 200 //in message 8 rc chan +#define MSP_SET_RAW_GPS 201 //in message fix, numsat, lat, lon, alt, speed +#define MSP_SET_PID 202 //in message up to 16 P I D (8 are used) +#define MSP_SET_BOX 203 //in message up to 16 checkbox (11 are used) +#define MSP_SET_RC_TUNING 204 //in message rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID +#define MSP_ACC_CALIBRATION 205 //in message no param +#define MSP_MAG_CALIBRATION 206 //in message no param +#define MSP_SET_MISC 207 //in message powermeter trig + 8 free for future use +#define MSP_RESET_CONF 208 //in message no param + +#define MSP_EEPROM_WRITE 250 //in message no param + +#define MSP_DEBUG 254 //out message debug1,debug2,debug3,debug4 + +static uint8_t checksum, stateMSP, indRX, inBuf[64]; + +void serialize32(uint32_t a) +{ + static uint8_t t; + t = a; + uartWrite(t); + checksum ^= t; + t = a >> 8; + uartWrite(t); + checksum ^= t; + t = a >> 16; + uartWrite(t); + checksum ^= t; + t = a >> 24; + uartWrite(t); + checksum ^= t; +} void serialize16(int16_t a) { - uartWrite(a); - uartWrite(a >> 8 & 0xff); + static uint8_t t; + t = a; + uartWrite(t); + checksum ^= t; + t = a >> 8 & 0xff; + uartWrite(t); + checksum ^= t; } void serialize8(uint8_t a) { uartWrite(a); + checksum ^= a; } +uint32_t read32(void) +{ + uint32_t t = inBuf[indRX++]; + t+= inBuf[indRX++] << 8; + t+= (uint32_t)inBuf[indRX++] << 16; + t+= (uint32_t)inBuf[indRX++] << 24; + return t; +} + +uint16_t read16(void) +{ + uint16_t t = inBuf[indRX++]; + t+= inBuf[indRX++] << 8; + return t; +} + +uint8_t read8(void) +{ + return inBuf[indRX++] & 0xff; +} + +void headSerialReply(uint8_t c, uint8_t s) +{ + serialize8('$'); + serialize8('M'); + serialize8('>'); + serialize8(s); + serialize8(c); + checksum = 0; +} + +void tailSerialReply(void) +{ + serialize8(checksum); + // no need to send + // UartSendData(); +} + +// signal that we're in cli mode +uint8_t cliMode = 0; + void serialInit(uint32_t baudrate) { uartInit(baudrate); } void serialCom(void) +{ + uint8_t i, c; + static uint8_t offset, dataSize; + + // in cli mode, all uart stuff goes to here. enter cli mode by sending # + if (cliMode) { + cliProcess(); + return; + } + + while (uartAvailable()) { + c = uartRead(); + + if (stateMSP > 99) { // a message with a length indication, indicating a non null payload + if (offset <= dataSize) { // there are still some octets to read (including checksum) to complete a full message + if (offset < dataSize) + checksum ^= c; // the checksum is computed, except for the last octet + inBuf[offset++] = c; + } else { // we have read all the payload + if (checksum == inBuf[dataSize]) { // we check is the computed checksum is ok + switch (stateMSP) { // if yes, then we execute different code depending on the message code. read8/16/32 will look into the inBuf buffer + case MSP_SET_RAW_RC: + for (i = 0; i < 8; i++) { + rcData[i] = read16(); + } + break; + case MSP_SET_RAW_GPS: + GPS_fix = read8(); + GPS_numSat = read8(); + GPS_latitude = read32(); + GPS_longitude = read32(); + GPS_altitude = read16(); + GPS_speed = read16(); + GPS_update = 1; + break; + case MSP_SET_PID: + for (i = 0; i < PIDITEMS; i++) { + cfg.P8[i] = read8(); + cfg.I8[i] = read8(); + cfg.D8[i] = read8(); + } + break; + case MSP_SET_BOX: + for (i = 0; i < CHECKBOXITEMS; i++) { + cfg.activate[i] = read16(); + } + break; + case MSP_SET_RC_TUNING: + cfg.rcRate8 = read8(); + cfg.rcExpo8 = read8(); + cfg.rollPitchRate = read8(); + cfg.yawRate = read8(); + cfg.dynThrPID = read8(); + cfg.thrMid8 = read8(); + cfg.thrExpo8 = read8(); + break; + case MSP_SET_MISC: + break; + } + } + stateMSP = 0; // in any case we reset the MSP state + } + } + + if (stateMSP < 5) { + if (stateMSP == 4) { // this protocol state indicates we have a message with a lenght indication, and we read here the message code (fifth octet) + if (c > 99) { // we check if it's a valid code (should be >99) + stateMSP = c; // the message code is then reuse to feed the protocol state + offset = 0; + checksum = 0; + indRX = 0; // and we init some values which will be used in the next loops to grasp the payload + } else { + stateMSP = 0; // the message code seems to be invalid. this should not happen => we reset the protocol state + } + } + if (stateMSP == 3) { // here, we need to check if the fourth octet indicates a code indication (>99) or a payload lenght indication (<100) + if (c < 100) { // a message with a length indication, indicating a non null payload + stateMSP++; // we update the protocol state to read the next octet + dataSize = c; // we store the payload lenght + if (dataSize > 63) + dataSize = 63; // in order to avoid overflow, we limit the size. this should not happen + } else { + switch (c) { // if we are here, the fourth octet indicates a code message + case MSP_IDENT: // and we check message code to execute the relative code + headSerialReply(c, 2); // we reply with an header indicating a payload lenght of 2 octets + serialize8(VERSION); // the first octet. serialize8/16/32 is used also to compute a checksum + serialize8(cfg.mixerConfiguration); // the second one + tailSerialReply(); + break; // mainly to send the last octet which is the checksum + case MSP_STATUS: + headSerialReply(c, 8); + serialize16(cycleTime); + serialize16(i2cGetErrorCounter()); + serialize16(sensors(SENSOR_ACC) | sensors(SENSOR_BARO) << 1 | sensors(SENSOR_MAG) << 2 | sensors(SENSOR_GPS) << 3 | sensors(SENSOR_SONAR) << 4); + serialize16(accMode << BOXACC | baroMode << BOXBARO | magMode << BOXMAG | armed << BOXARM | GPSModeHome << BOXGPSHOME | GPSModeHold << BOXGPSHOLD | headFreeMode << BOXHEADFREE); + tailSerialReply(); + break; + case MSP_RAW_IMU: + headSerialReply(c, 18); + for (i = 0; i < 3; i++) + serialize16(accSmooth[i]); + for (i = 0; i < 3; i++) + serialize16(gyroData[i]); + for (i = 0; i < 3; i++) + serialize16(magADC[i]); + tailSerialReply(); + break; + case MSP_SERVO: + headSerialReply(c, 16); + for (i = 0; i < 8; i++) + serialize16(servo[i]); + tailSerialReply(); + break; + case MSP_MOTOR: + headSerialReply(c, 16); + for (i = 0; i < 8; i++) + serialize16(motor[i]); + tailSerialReply(); + break; + case MSP_RC: + headSerialReply(c, 16); + for (i = 0; i < 8; i++) + serialize16(rcData[i]); + tailSerialReply(); + break; + case MSP_RAW_GPS: + headSerialReply(c, 14); + serialize8(GPS_fix); + serialize8(GPS_numSat); + serialize32(GPS_latitude); + serialize32(GPS_longitude); + serialize16(GPS_altitude); + serialize16(GPS_speed); + tailSerialReply(); + break; + case MSP_COMP_GPS: + headSerialReply(c, 5); + serialize16(GPS_distanceToHome); + serialize16(GPS_directionToHome + 180); + serialize8(GPS_update); + tailSerialReply(); + break; + case MSP_ATTITUDE: + headSerialReply(c, 6); + for (i = 0; i < 2; i++) + serialize16(angle[i]); + serialize16(heading); + tailSerialReply(); + break; + case MSP_ALTITUDE: + headSerialReply(c, 4); + serialize32(EstAlt); + tailSerialReply(); + break; + case MSP_BAT: + headSerialReply(c, 3); + serialize8(vbat); + serialize16(0); + tailSerialReply(); + break; + case MSP_RC_TUNING: + headSerialReply(c, 7); + serialize8(cfg.rcRate8); + serialize8(cfg.rcExpo8); + serialize8(cfg.rollPitchRate); + serialize8(cfg.yawRate); + serialize8(cfg.dynThrPID); + serialize8(cfg.thrMid8); + serialize8(cfg.thrExpo8); + tailSerialReply(); + break; + case MSP_PID: + headSerialReply(c, 3 * PIDITEMS); + for (i = 0; i < PIDITEMS; i++) { + serialize8(cfg.P8[i]); + serialize8(cfg.I8[i]); + serialize8(cfg.D8[i]); + } + tailSerialReply(); + break; + case MSP_BOX: + headSerialReply(c, 2 * CHECKBOXITEMS); + for (i = 0; i < CHECKBOXITEMS; i++) { + serialize16(cfg.activate[i]); + } + tailSerialReply(); + break; + case MSP_MISC: + headSerialReply(c, 2); + serialize16(0); + tailSerialReply(); + break; + case MSP_RESET_CONF: + checkFirstTime(true); + break; + case MSP_ACC_CALIBRATION: + calibratingA = 400; + break; + case MSP_MAG_CALIBRATION: + calibratingM = 1; + break; + case MSP_EEPROM_WRITE: + writeParams(0); + break; + case MSP_DEBUG: + headSerialReply(c, 8); + serialize16(debug1); // 4 variables are here for general monitoring purpose + serialize16(debug2); + serialize16(debug3); + serialize16(debug4); + tailSerialReply(); + break; + } + stateMSP = 0; // we reset the protocol state for the next loop + } + } else { + switch (c) { // header detection $MW< + case '$': + if (stateMSP == 0) + stateMSP++; + break; // first octet ok, no need to go further + case 'M': + if (stateMSP == 1) + stateMSP++; + break; // second octet ok, no need to go further + case '<': + if (stateMSP == 2) + stateMSP++; + break; // third octet ok, no need to go further + } + } + } + if (stateMSP == 0) { // still compliant with older single octet command + // enable CLI + if (c == '#') + cliProcess(); + } + } +} + +#if 0 +void oldSserialCom(void) { uint8_t i; @@ -83,10 +418,8 @@ void serialCom(void) serialize8(cfg.rollPitchRate); serialize8(cfg.yawRate); serialize8(cfg.dynThrPID); - for (i = 0; i < CHECKBOXITEMS; i++) { - serialize8(cfg.activate1[i]); - serialize8(cfg.activate2[i] | (rcOptions[i] << 7)); // use highest bit to transport state in mwc - } + for (i = 0; i < CHECKBOXITEMS; i++) + serialize16(cfg.activate[i]); serialize16(GPS_distanceToHome); serialize16(GPS_directionToHome + 180); serialize8(GPS_numSat); @@ -145,13 +478,11 @@ void serialCom(void) cfg.rollPitchRate = uartReadPoll(); cfg.yawRate = uartReadPoll(); //4 cfg.dynThrPID = uartReadPoll(); //5 - for (i = 0; i < CHECKBOXITEMS; i++) { - cfg.activate1[i] = uartReadPoll(); - cfg.activate2[i] = uartReadPoll(); - } + for (i = 0; i < CHECKBOXITEMS; i++) + cfg.activate[i] = uartReadPoll(); uartReadPoll(); // power meter crap, removed uartReadPoll(); // power meter crap, removed - writeParams(); + writeParams(0); break; case 'S': // GUI to arduino ACC calibration request calibratingA = 400; @@ -162,3 +493,4 @@ void serialCom(void) } } } +#endif