1 /* By Larry Ho Ka Wai @ 23/06/2015*/
9 #include "build/build_config.h"
10 #include "build/debug.h"
11 #include "build/version.h"
15 #include "common/axis.h"
16 #include "common/color.h"
17 #include "common/maths.h"
19 #include "drivers/system.h"
21 #include "drivers/sensor.h"
22 #include "drivers/accgyro.h"
23 #include "drivers/compass.h"
25 #include "drivers/serial.h"
26 #include "drivers/bus_i2c.h"
27 #include "drivers/gpio.h"
28 #include "drivers/timer.h"
29 #include "drivers/rx_pwm.h"
31 #include "fc/config.h"
32 #include "fc/controlrate_profile.h"
33 #include "fc/fc_core.h"
34 #include "fc/rc_adjustments.h"
35 #include "fc/rc_controls.h"
36 #include "fc/runtime_config.h"
38 #include "io/motors.h"
39 #include "io/servos.h"
41 #include "io/gimbal.h"
42 #include "io/serial.h"
43 #include "io/ledstrip.h"
44 #include "io/flashfs.h"
45 #include "io/beeper.h"
50 #include "scheduler/scheduler.h"
52 #include "sensors/boardalignment.h"
53 #include "sensors/sensors.h"
54 #include "sensors/battery.h"
55 #include "sensors/sonar.h"
56 #include "sensors/acceleration.h"
57 #include "sensors/barometer.h"
58 #include "sensors/compass.h"
59 #include "sensors/gyro.h"
61 #include "telemetry/telemetry.h"
63 #include "flight/altitudehold.h"
64 #include "flight/failsafe.h"
65 #include "flight/imu.h"
66 #include "flight/mixer.h"
67 #include "flight/navigation.h"
68 #include "flight/pid.h"
69 #include "flight/servos.h"
71 #include "config/config_eeprom.h"
72 #include "config/config_profile.h"
73 #include "config/feature.h"
78 #define GPS_POSITION_FRAME_ID 0x02
79 #define GPS_TIME_FRAME_ID 0x03
80 #define FC_ATTITUDE_FRAME_ID 0x1E
81 #define RC_CHANNEL_FRAME_ID 0x15
82 #define CROSSFIRE_RSSI_FRAME_ID 0x14
83 #define CLEANFLIGHT_MODE_FRAME_ID 0x20
85 #define BST_PROTOCOL_VERSION 0
87 #define API_VERSION_MAJOR 1 // increment when major changes are made
88 #define API_VERSION_MINOR 13 // increment when any change is made, reset to zero when major changes are released after changing API_VERSION_MAJOR
90 #define API_VERSION_LENGTH 2
93 // MSP commands for Cleanflight original features
96 #define BST_API_VERSION 1 //out message
97 #define BST_FC_VARIANT 2 //out message
98 #define BST_FC_VERSION 3 //out message
99 #define BST_BOARD_INFO 4 //out message
100 #define BST_BUILD_INFO 5 //out message
102 #define BST_MODE_RANGES 34 //out message Returns all mode ranges
103 #define BST_SET_MODE_RANGE 35 //in message Sets a single mode range
104 #define BST_FEATURE 36
105 #define BST_SET_FEATURE 37
106 #define BST_RX_CONFIG 44
107 #define BST_SET_RX_CONFIG 45
108 #define BST_LED_COLORS 46
109 #define BST_SET_LED_COLORS 47
110 #define BST_LED_STRIP_CONFIG 48
111 #define BST_SET_LED_STRIP_CONFIG 49
112 #define BST_LOOP_TIME 83 //out message Returns FC cycle time i.e looptime parameter
113 #define BST_SET_LOOP_TIME 84 //in message Sets FC cycle time i.e looptime parameter
114 #define BST_RX_MAP 64 //out message Get channel map (also returns number of channels total)
115 #define BST_SET_RX_MAP 65 //in message Set rx map, numchannels to set comes from BST_RX_MAP
116 #define BST_REBOOT 68 //in message Reboot
117 #define BST_DISARM 70 //in message Disarm
118 #define BST_ENABLE_ARM 71 //in message Enable arm
119 #define BST_DEADBAND 72 //out message
120 #define BST_SET_DEADBAND 73 //in message
121 #define BST_FC_FILTERS 74 //out message
122 #define BST_SET_FC_FILTERS 75 //in message
123 #define BST_STATUS 101 //out message cycletime & errors_count & sensor present & box activation & current setting number
124 #define BST_RC_TUNING 111 //out message rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID
125 #define BST_PID 112 //out message P I D coeff (9 are used currently)
126 #define BST_MISC 114 //out message powermeter trig
127 #define BST_SET_PID 202 //in message P I D coeff (9 are used currently)
128 #define BST_ACC_CALIBRATION 205 //in message no param
129 #define BST_MAG_CALIBRATION 206 //in message no param
130 #define BST_SET_MISC 207 //in message powermeter trig + 8 free for future use
131 #define BST_SELECT_SETTING 210 //in message Select Setting Number (0-2)
132 #define BST_EEPROM_WRITE 250 //in message no param
134 extern volatile uint8_t CRC8
;
135 extern volatile bool coreProReady
;
137 // this is calculated at startup based on enabled features.
138 static uint8_t activeBoxIds
[CHECKBOX_ITEM_COUNT
];
139 // this is the number of filled indexes in above array
140 static uint8_t activeBoxIdCount
= 0;
142 extern int16_t motor_disarmed
[MAX_SUPPORTED_MOTORS
];
144 // cause reboot after BST processing complete
145 static bool isRebootScheduled
= false;
147 typedef struct box_e
{
148 const uint8_t boxId
; // see boxId_e
149 const char *boxName
; // GUI-readable box name
150 const uint8_t permanentId
; //
154 static const box_t boxes
[CHECKBOX_ITEM_COUNT
+ 1] = {
155 { BOXARM
, "ARM;", 0 },
156 { BOXANGLE
, "ANGLE;", 1 },
157 { BOXHORIZON
, "HORIZON;", 2 },
158 { BOXBARO
, "BARO;", 3 },
159 //{ BOXVARIO, "VARIO;", 4 },
160 { BOXMAG
, "MAG;", 5 },
161 { BOXHEADFREE
, "HEADFREE;", 6 },
162 { BOXHEADADJ
, "HEADADJ;", 7 },
163 { BOXCAMSTAB
, "CAMSTAB;", 8 },
164 { BOXCAMTRIG
, "CAMTRIG;", 9 },
165 { BOXGPSHOME
, "GPS HOME;", 10 },
166 { BOXGPSHOLD
, "GPS HOLD;", 11 },
167 { BOXPASSTHRU
, "PASSTHRU;", 12 },
168 { BOXBEEPERON
, "BEEPER;", 13 },
169 { BOXLEDMAX
, "LEDMAX;", 14 },
170 { BOXLEDLOW
, "LEDLOW;", 15 },
171 { BOXLLIGHTS
, "LLIGHTS;", 16 },
172 { BOXCALIB
, "CALIB;", 17 },
173 { BOXGOV
, "GOVERNOR;", 18 },
174 { BOXOSD
, "OSD SW;", 19 },
175 { BOXTELEMETRY
, "TELEMETRY;", 20 },
176 { BOXGTUNE
, "GTUNE;", 21 },
177 { BOXSONAR
, "SONAR;", 22 },
178 { BOXSERVO1
, "SERVO1;", 23 },
179 { BOXSERVO2
, "SERVO2;", 24 },
180 { BOXSERVO3
, "SERVO3;", 25 },
181 { BOXBLACKBOX
, "BLACKBOX;", 26 },
182 { BOXFAILSAFE
, "FAILSAFE;", 27 },
183 { CHECKBOX_ITEM_COUNT
, NULL
, 0xFF }
186 extern uint8_t readData
[BST_BUFFER_SIZE
];
187 extern uint8_t writeData
[BST_BUFFER_SIZE
];
189 /*************************************************************************************************/
190 uint8_t writeBufferPointer
= 1;
191 static void bstWrite8(uint8_t data
) {
192 writeData
[writeBufferPointer
++] = data
;
193 writeData
[0] = writeBufferPointer
;
196 static void bstWrite16(uint16_t data
)
198 bstWrite8((uint8_t)(data
>> 0));
199 bstWrite8((uint8_t)(data
>> 8));
202 static void bstWrite32(uint32_t data
)
204 bstWrite16((uint16_t)(data
>> 0));
205 bstWrite16((uint16_t)(data
>> 16));
208 uint8_t readBufferPointer
= 4;
209 static uint8_t bstCurrentAddress(void)
214 static uint8_t bstRead8(void)
216 return readData
[readBufferPointer
++] & 0xff;
219 static uint16_t bstRead16(void)
221 uint16_t t
= bstRead8();
222 t
+= (uint16_t)bstRead8() << 8;
226 static uint32_t bstRead32(void)
228 uint32_t t
= bstRead16();
229 t
+= (uint32_t)bstRead16() << 16;
233 static uint8_t bstReadDataSize(void)
235 return readData
[1]-5;
238 static uint8_t bstReadCRC(void)
240 return readData
[readData
[1]+1];
243 static const box_t
*findBoxByPermenantId(uint8_t permenantId
)
246 const box_t
*candidate
;
247 for (boxIndex
= 0; boxIndex
< sizeof(boxes
) / sizeof(box_t
); boxIndex
++) {
248 candidate
= &boxes
[boxIndex
];
249 if (candidate
->permanentId
== permenantId
) {
256 #define IS_ENABLED(mask) (mask == 0 ? 0 : 1)
258 /*************************************************************************************************/
259 #define BST_USB_COMMANDS 0x0A
260 #define BST_GENERAL_HEARTBEAT 0x0B
261 #define BST_USB_DEVICE_INFO_REQUEST 0x04 //Handshake
262 #define BST_USB_DEVICE_INFO_FRAME 0x05 //Handshake
263 #define BST_READ_COMMANDS 0x26
264 #define BST_WRITE_COMMANDS 0x25
265 #define BST_PASSED 0x01
266 #define BST_FAILED 0x00
268 static bool bstSlaveProcessFeedbackCommand(uint8_t bstRequest
)
270 uint32_t i
, tmp
, junk
;
273 case BST_API_VERSION
:
274 bstWrite8(BST_PROTOCOL_VERSION
);
276 bstWrite8(API_VERSION_MAJOR
);
277 bstWrite8(API_VERSION_MINOR
);
280 for (i
= 0; i
< BUILD_DATE_LENGTH
; i
++) {
281 bstWrite8(buildDate
[i
]);
283 for (i
= 0; i
< BUILD_TIME_LENGTH
; i
++) {
284 bstWrite8(buildTime
[i
]);
287 for (i
= 0; i
< GIT_SHORT_REVISION_LENGTH
; i
++) {
288 bstWrite8(shortGitRevision
[i
]);
292 bstWrite16(getTaskDeltaTime(TASK_GYROPID
));
294 bstWrite16(i2cGetErrorCounter());
298 bstWrite16(sensors(SENSOR_ACC
) | sensors(SENSOR_BARO
) << 1 | sensors(SENSOR_MAG
) << 2 | sensors(SENSOR_GPS
) << 3 | sensors(SENSOR_SONAR
) << 4);
299 // BST the flags in the order we delivered them, ignoring BOXNAMES and BOXINDEXES
300 // Requires new Multiwii protocol version to fix
301 // It would be preferable to setting the enabled bits based on BOXINDEX.
303 tmp
= IS_ENABLED(FLIGHT_MODE(ANGLE_MODE
)) << BOXANGLE
|
304 IS_ENABLED(FLIGHT_MODE(HORIZON_MODE
)) << BOXHORIZON
|
305 IS_ENABLED(FLIGHT_MODE(BARO_MODE
)) << BOXBARO
|
306 IS_ENABLED(FLIGHT_MODE(MAG_MODE
)) << BOXMAG
|
307 IS_ENABLED(FLIGHT_MODE(HEADFREE_MODE
)) << BOXHEADFREE
|
308 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXHEADADJ
)) << BOXHEADADJ
|
309 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXCAMSTAB
)) << BOXCAMSTAB
|
310 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXCAMTRIG
)) << BOXCAMTRIG
|
311 IS_ENABLED(FLIGHT_MODE(GPS_HOME_MODE
)) << BOXGPSHOME
|
312 IS_ENABLED(FLIGHT_MODE(GPS_HOLD_MODE
)) << BOXGPSHOLD
|
313 IS_ENABLED(FLIGHT_MODE(PASSTHRU_MODE
)) << BOXPASSTHRU
|
314 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXBEEPERON
)) << BOXBEEPERON
|
315 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXLEDMAX
)) << BOXLEDMAX
|
316 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXLEDLOW
)) << BOXLEDLOW
|
317 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXLLIGHTS
)) << BOXLLIGHTS
|
318 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXCALIB
)) << BOXCALIB
|
319 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXGOV
)) << BOXGOV
|
320 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXOSD
)) << BOXOSD
|
321 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXTELEMETRY
)) << BOXTELEMETRY
|
322 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXGTUNE
)) << BOXGTUNE
|
323 IS_ENABLED(FLIGHT_MODE(SONAR_MODE
)) << BOXSONAR
|
324 IS_ENABLED(ARMING_FLAG(ARMED
)) << BOXARM
|
325 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXBLACKBOX
)) << BOXBLACKBOX
|
326 IS_ENABLED(FLIGHT_MODE(FAILSAFE_MODE
)) << BOXFAILSAFE
;
327 for (i
= 0; i
< activeBoxIdCount
; i
++) {
328 int flag
= (tmp
& (1 << activeBoxIds
[i
]));
333 bstWrite8(getCurrentPidProfileIndex());
336 bstWrite16(getTaskDeltaTime(TASK_GYROPID
));
339 bstWrite8(currentControlRateProfile
->rcRate8
);
340 bstWrite8(currentControlRateProfile
->rcExpo8
);
341 for (i
= 0 ; i
< 3; i
++) {
342 bstWrite8(currentControlRateProfile
->rates
[i
]); // R,P,Y see flight_dynamics_index_t
344 bstWrite8(currentControlRateProfile
->dynThrPID
);
345 bstWrite8(currentControlRateProfile
->thrMid8
);
346 bstWrite8(currentControlRateProfile
->thrExpo8
);
347 bstWrite16(currentControlRateProfile
->tpa_breakpoint
);
348 bstWrite8(currentControlRateProfile
->rcYawExpo8
);
349 bstWrite8(currentControlRateProfile
->rcYawRate8
);
352 for (i
= 0; i
< PID_ITEM_COUNT
; i
++) {
353 bstWrite8(currentPidProfile
->P8
[i
]);
354 bstWrite8(currentPidProfile
->I8
[i
]);
355 bstWrite8(currentPidProfile
->D8
[i
]);
357 pidInitConfig(currentPidProfile
);
359 case BST_MODE_RANGES
:
360 for (i
= 0; i
< MAX_MODE_ACTIVATION_CONDITION_COUNT
; i
++) {
361 const modeActivationCondition_t
*mac
= modeActivationConditions(i
);
362 const box_t
*box
= &boxes
[mac
->modeId
];
363 bstWrite8(box
->permanentId
);
364 bstWrite8(mac
->auxChannelIndex
);
365 bstWrite8(mac
->range
.startStep
);
366 bstWrite8(mac
->range
.endStep
);
370 bstWrite16(rxConfig()->midrc
);
372 bstWrite16(motorConfig()->minthrottle
);
373 bstWrite16(motorConfig()->maxthrottle
);
374 bstWrite16(motorConfig()->mincommand
);
376 bstWrite16(failsafeConfig()->failsafe_throttle
);
379 bstWrite8(gpsConfig()->provider
); // gps_type
380 bstWrite8(0); // TODO gps_baudrate (an index, cleanflight uses a uint32_t
381 bstWrite8(gpsConfig()->sbasMode
); // gps_ubx_sbas
383 bstWrite8(0); // gps_type
384 bstWrite8(0); // TODO gps_baudrate (an index, cleanflight uses a uint32_t
385 bstWrite8(0); // gps_ubx_sbas
387 bstWrite8(0); // legacy - was multiwiiCurrentMeterOutput);
388 bstWrite8(rxConfig()->rssi_channel
);
391 bstWrite16(compassConfig()->mag_declination
/ 10);
393 bstWrite8(voltageSensorADCConfig(VOLTAGE_SENSOR_ADC_VBAT
)->vbatscale
);
394 bstWrite8(batteryConfig()->vbatmincellvoltage
);
395 bstWrite8(batteryConfig()->vbatmaxcellvoltage
);
396 bstWrite8(batteryConfig()->vbatwarningcellvoltage
);
400 bstWrite32(featureMask());
404 bstWrite8(rxConfig()->serialrx_provider
);
405 bstWrite16(rxConfig()->maxcheck
);
406 bstWrite16(rxConfig()->midrc
);
407 bstWrite16(rxConfig()->mincheck
);
408 bstWrite8(rxConfig()->spektrum_sat_bind
);
409 bstWrite16(rxConfig()->rx_min_usec
);
410 bstWrite16(rxConfig()->rx_max_usec
);
414 for (i
= 0; i
< MAX_MAPPABLE_RX_INPUTS
; i
++)
415 bstWrite8(rxConfig()->rcmap
[i
]);
421 for (i
= 0; i
< LED_CONFIGURABLE_COLOR_COUNT
; i
++) {
422 hsvColor_t
*color
= &ledStripConfigMutable()->colors
[i
];
423 bstWrite16(color
->h
);
429 case BST_LED_STRIP_CONFIG
:
430 for (i
= 0; i
< LED_MAX_STRIP_LENGTH
; i
++) {
431 const ledConfig_t
*ledConfig
= &ledStripConfig()->ledConfigs
[i
];
432 bstWrite32(*ledConfig
);
437 bstWrite8(rcControlsConfig()->alt_hold_deadband
);
438 bstWrite8(rcControlsConfig()->alt_hold_fast_change
);
439 bstWrite8(rcControlsConfig()->deadband
);
440 bstWrite8(rcControlsConfig()->yaw_deadband
);
443 bstWrite16(constrain(gyroConfig()->gyro_lpf
, 0, 1)); // Extra safety to prevent OSD setting corrupt values
446 // we do not know how to handle the (valid) message, indicate error BST
452 static bool bstSlaveProcessWriteCommand(uint8_t bstWriteCommand
)
457 bool ret
= BST_PASSED
;
458 switch(bstWriteCommand
) {
459 case BST_SELECT_SETTING
:
460 if (!ARMING_FLAG(ARMED
)) {
461 changePidProfile(bstRead8());
464 case BST_SET_LOOP_TIME
:
468 for (i
= 0; i
< PID_ITEM_COUNT
; i
++) {
469 currentPidProfile
->P8
[i
] = bstRead8();
470 currentPidProfile
->I8
[i
] = bstRead8();
471 currentPidProfile
->D8
[i
] = bstRead8();
474 case BST_SET_MODE_RANGE
:
476 if (i
< MAX_MODE_ACTIVATION_CONDITION_COUNT
) {
477 modeActivationCondition_t
*mac
= modeActivationConditionsMutable(i
);
479 const box_t
*box
= findBoxByPermenantId(i
);
481 mac
->modeId
= box
->boxId
;
482 mac
->auxChannelIndex
= bstRead8();
483 mac
->range
.startStep
= bstRead8();
484 mac
->range
.endStep
= bstRead8();
486 useRcControlsConfig(modeActivationConditions(0), currentPidProfile
);
496 if (tmp
< 1600 && tmp
> 1400)
497 rxConfigMutable()->midrc
= tmp
;
499 motorConfigMutable()->minthrottle
= bstRead16();
500 motorConfigMutable()->maxthrottle
= bstRead16();
501 motorConfigMutable()->mincommand
= bstRead16();
503 failsafeConfigMutable()->failsafe_throttle
= bstRead16();
506 gpsConfigMutable()->provider
= bstRead8(); // gps_type
507 bstRead8(); // gps_baudrate
508 gpsConfigMutable()->sbasMode
= bstRead8(); // gps_ubx_sbas
510 bstRead8(); // gps_type
511 bstRead8(); // gps_baudrate
512 bstRead8(); // gps_ubx_sbas
514 bstRead8(); // legacy - was multiwiiCurrentMeterOutput
515 rxConfigMutable()->rssi_channel
= bstRead8();
518 compassConfigMutable()->mag_declination
= bstRead16() * 10;
520 voltageSensorADCConfigMutable(VOLTAGE_SENSOR_ADC_VBAT
)->vbatscale
= bstRead8(); // actual vbatscale as intended
521 batteryConfigMutable()->vbatmincellvoltage
= bstRead8(); // vbatlevel_warn1 in MWC2.3 GUI
522 batteryConfigMutable()->vbatmaxcellvoltage
= bstRead8(); // vbatlevel_warn2 in MWC2.3 GUI
523 batteryConfigMutable()->vbatwarningcellvoltage
= bstRead8(); // vbatlevel when buzzer starts to alert
526 case BST_ACC_CALIBRATION
:
527 if (!ARMING_FLAG(ARMED
))
528 accSetCalibrationCycles(CALIBRATING_ACC_CYCLES
);
530 case BST_MAG_CALIBRATION
:
531 if (!ARMING_FLAG(ARMED
))
532 ENABLE_STATE(CALIBRATE_MAG
);
534 case BST_EEPROM_WRITE
:
535 if (ARMING_FLAG(ARMED
)) {
543 case BST_SET_FEATURE
:
545 featureSet(bstRead32()); // features bitmap
547 if (featureConfigured(FEATURE_RX_SERIAL
)) {
548 serialConfigMutable()->portConfigs
[SERIALRX_UART
].functionMask
= FUNCTION_RX_SERIAL
;
550 serialConfigMutable()->portConfigs
[SERIALRX_UART
].functionMask
= FUNCTION_NONE
;
554 case BST_SET_RX_CONFIG
:
555 rxConfigMutable()->serialrx_provider
= bstRead8();
556 rxConfigMutable()->maxcheck
= bstRead16();
557 rxConfigMutable()->midrc
= bstRead16();
558 rxConfigMutable()->mincheck
= bstRead16();
559 rxConfigMutable()->spektrum_sat_bind
= bstRead8();
560 if (bstReadDataSize() > 8) {
561 rxConfigMutable()->rx_min_usec
= bstRead16();
562 rxConfigMutable()->rx_max_usec
= bstRead16();
566 for (i
= 0; i
< MAX_MAPPABLE_RX_INPUTS
; i
++) {
567 rxConfigMutable()->rcmap
[i
] = bstRead8();
572 case BST_SET_LED_COLORS
:
573 //for (i = 0; i < CONFIGURABLE_COLOR_COUNT; i++) {
576 hsvColor_t
*color
= &ledStripConfigMutable()->colors
[i
];
577 color
->h
= bstRead16();
578 color
->s
= bstRead8();
579 color
->v
= bstRead8();
582 case BST_SET_LED_STRIP_CONFIG
:
585 if (i
>= LED_MAX_STRIP_LENGTH
|| bstReadDataSize() != (1 + 4)) {
589 ledConfig_t
*ledConfig
= &ledStripConfigMutable()->ledConfigs
[i
];
590 *ledConfig
= bstRead32();
591 reevaluateLedConfig();
596 isRebootScheduled
= true;
599 if (ARMING_FLAG(ARMED
))
601 ENABLE_ARMING_FLAG(PREVENT_ARMING
);
604 DISABLE_ARMING_FLAG(PREVENT_ARMING
);
606 case BST_SET_DEADBAND
:
607 rcControlsConfigMutable()->alt_hold_deadband
= bstRead8();
608 rcControlsConfigMutable()->alt_hold_fast_change
= bstRead8();
609 rcControlsConfigMutable()->deadband
= bstRead8();
610 rcControlsConfigMutable()->yaw_deadband
= bstRead8();
612 case BST_SET_FC_FILTERS
:
613 gyroConfigMutable()->gyro_lpf
= bstRead16();
617 // we do not know how to handle the (valid) message, indicate error BST
622 if(ret
== BST_FAILED
)
628 static bool bstSlaveUSBCommandFeedback(/*uint8_t bstFeedback*/)
630 bstWrite8(BST_USB_DEVICE_INFO_FRAME
); //Sub CPU Device Info FRAME
631 bstWrite8(sensors(SENSOR_ACC
) | sensors(SENSOR_BARO
) << 1 | sensors(SENSOR_MAG
) << 2 | sensors(SENSOR_GPS
) << 3 | sensors(SENSOR_SONAR
) << 4);
635 bstWrite8(FC_VERSION_MAJOR
); //Firmware ID
636 bstWrite8(FC_VERSION_MINOR
); //Firmware ID
642 /*************************************************************************************************/
643 #define BST_RESET_TIME 1.2*1000*1000 //micro-seconds
645 uint32_t resetBstTimer
= 0;
646 bool needResetCheck
= true;
648 extern bool cleanflight_data_ready
;
650 void bstProcessInCommand(void)
652 readBufferPointer
= 2;
653 if(bstCurrentAddress() == I2C_ADDR_CLEANFLIGHT_FC
) {
654 if(bstReadCRC() == CRC8
&& bstRead8()==BST_USB_COMMANDS
) {
656 writeBufferPointer
= 1;
657 cleanflight_data_ready
= false;
658 for(i
= 0; i
< BST_BUFFER_SIZE
; i
++) {
661 switch (bstRead8()) {
662 case BST_USB_DEVICE_INFO_REQUEST
:
664 if(bstSlaveUSBCommandFeedback(/*bstRead8()*/))
667 case BST_READ_COMMANDS
:
668 bstWrite8(BST_READ_COMMANDS
);
669 bstSlaveProcessFeedbackCommand(bstRead8());
671 case BST_WRITE_COMMANDS
:
672 bstWrite8(BST_WRITE_COMMANDS
);
673 bstSlaveProcessWriteCommand(bstRead8());
676 // we do not know how to handle the (valid) message, indicate error BST
679 cleanflight_data_ready
= true;
681 } else if(bstCurrentAddress() == 0x00) {
682 if(bstReadCRC() == CRC8
&& bstRead8()==BST_GENERAL_HEARTBEAT
) {
683 resetBstTimer
= micros();
684 needResetCheck
= true;
689 static void resetBstChecker(timeUs_t currentTimeUs
)
692 if(currentTimeUs
>= (resetBstTimer
+ BST_RESET_TIME
))
694 bstTimeoutUserCallback();
695 needResetCheck
= false;
700 /*************************************************************************************************/
701 #define UPDATE_AT_02HZ ((1000 * 1000) / 2)
702 static uint32_t next02hzUpdateAt_1
= 0;
704 #define UPDATE_AT_20HZ ((1000 * 1000) / 20)
705 static uint32_t next20hzUpdateAt_1
= 0;
707 static uint8_t sendCounter
= 0;
709 void taskBstMasterProcess(timeUs_t currentTimeUs
)
712 if(currentTimeUs
>= next02hzUpdateAt_1
&& !bstWriteBusy()) {
714 next02hzUpdateAt_1
= currentTimeUs
+ UPDATE_AT_02HZ
;
716 if(currentTimeUs
>= next20hzUpdateAt_1
&& !bstWriteBusy()) {
718 writeRCChannelToBST();
719 else if(sendCounter
== 1)
720 writeRollPitchYawToBST();
724 next20hzUpdateAt_1
= currentTimeUs
+ UPDATE_AT_20HZ
;
727 if(sensors(SENSOR_GPS
) && !bstWriteBusy())
728 writeGpsPositionPrameToBST();
732 bstMasterWriteLoop();
733 if (isRebootScheduled
) {
737 resetBstChecker(currentTimeUs
);
740 /*************************************************************************************************/
741 static uint8_t masterWriteBufferPointer
;
742 static uint8_t masterWriteData
[BST_BUFFER_SIZE
];
744 static void bstMasterStartBuffer(uint8_t address
)
746 masterWriteData
[0] = address
;
747 masterWriteBufferPointer
= 2;
750 static void bstMasterWrite8(uint8_t data
)
752 masterWriteData
[masterWriteBufferPointer
++] = data
;
753 masterWriteData
[1] = masterWriteBufferPointer
;
756 static void bstMasterWrite16(uint16_t data
)
758 bstMasterWrite8((uint8_t)(data
>> 8));
759 bstMasterWrite8((uint8_t)(data
>> 0));
762 /*************************************************************************************************/
763 #define PUBLIC_ADDRESS 0x00
766 static void bstMasterWrite32(uint32_t data
)
768 bstMasterWrite16((uint8_t)(data
>> 16));
769 bstMasterWrite16((uint8_t)(data
>> 0));
772 static int32_t lat
= 0;
773 static int32_t lon
= 0;
774 static uint16_t alt
= 0;
775 static uint8_t numOfSat
= 0;
779 bool writeGpsPositionPrameToBST(void)
781 if((lat
!= GPS_coord
[LAT
]) || (lon
!= GPS_coord
[LON
]) || (alt
!= GPS_altitude
) || (numOfSat
!= GPS_numSat
)) {
782 lat
= GPS_coord
[LAT
];
783 lon
= GPS_coord
[LON
];
785 numOfSat
= GPS_numSat
;
786 uint16_t speed
= (GPS_speed
* 9 / 25);
787 uint16_t gpsHeading
= 0;
788 uint16_t altitude
= 0;
789 gpsHeading
= GPS_ground_course
* 10;
790 altitude
= alt
* 10 + 1000;
792 bstMasterStartBuffer(PUBLIC_ADDRESS
);
793 bstMasterWrite8(GPS_POSITION_FRAME_ID
);
794 bstMasterWrite32(lat
);
795 bstMasterWrite32(lon
);
796 bstMasterWrite16(speed
);
797 bstMasterWrite16(gpsHeading
);
798 bstMasterWrite16(altitude
);
799 bstMasterWrite8(numOfSat
);
800 bstMasterWrite8(0x00);
802 return bstMasterWrite(masterWriteData
);
808 bool writeRollPitchYawToBST(void)
810 int16_t X
= -attitude
.values
.pitch
* (M_PIf
/ 1800.0f
) * 10000;
811 int16_t Y
= attitude
.values
.roll
* (M_PIf
/ 1800.0f
) * 10000;
812 int16_t Z
= 0;//radiusHeading * 10000;
814 bstMasterStartBuffer(PUBLIC_ADDRESS
);
815 bstMasterWrite8(FC_ATTITUDE_FRAME_ID
);
820 return bstMasterWrite(masterWriteData
);
823 bool writeRCChannelToBST(void)
826 bstMasterStartBuffer(PUBLIC_ADDRESS
);
827 bstMasterWrite8(RC_CHANNEL_FRAME_ID
);
828 for(i
= 0; i
< (USABLE_TIMER_CHANNEL_COUNT
-1); i
++) {
829 bstMasterWrite16(rcData
[i
]);
832 return bstMasterWrite(masterWriteData
);
835 bool writeFCModeToBST(void)
838 tmp
= IS_ENABLED(ARMING_FLAG(ARMED
)) |
839 IS_ENABLED(FLIGHT_MODE(ANGLE_MODE
)) << 1 |
840 IS_ENABLED(FLIGHT_MODE(HORIZON_MODE
)) << 2 |
841 IS_ENABLED(FLIGHT_MODE(BARO_MODE
)) << 3 |
842 IS_ENABLED(FLIGHT_MODE(MAG_MODE
)) << 4 |
843 IS_ENABLED(IS_RC_MODE_ACTIVE(BOXAIRMODE
)) << 5 |
844 IS_ENABLED(FLIGHT_MODE(SONAR_MODE
)) << 6 |
845 IS_ENABLED(FLIGHT_MODE(FAILSAFE_MODE
)) << 7;
847 bstMasterStartBuffer(PUBLIC_ADDRESS
);
848 bstMasterWrite8(CLEANFLIGHT_MODE_FRAME_ID
);
849 bstMasterWrite8(tmp
);
850 bstMasterWrite8(sensors(SENSOR_ACC
) | sensors(SENSOR_BARO
) << 1 | sensors(SENSOR_MAG
) << 2 | sensors(SENSOR_GPS
) << 3 | sensors(SENSOR_SONAR
) << 4);
852 return bstMasterWrite(masterWriteData
);
854 /*************************************************************************************************/