37 #include "physical_constants.h"
43 #include "actuatorsettings.h"
44 #include "actuatordesired.h"
45 #include "airspeedactual.h"
46 #include "attitudeactual.h"
47 #include "baroaltitude.h"
48 #include "flightbatterysettings.h"
49 #include "flightbatterystate.h"
50 #include "flightstatus.h"
51 #include "gpsposition.h"
52 #include "homelocation.h"
53 #include "manualcontrolcommand.h"
54 #include "modulesettings.h"
55 #include "positionactual.h"
56 #include "stabilizationsettings.h"
57 #include "systemalarms.h"
58 #include "systemsettings.h"
59 #include "systemstats.h"
62 #if defined(PIOS_INCLUDE_MSP_BRIDGE)
64 #define MSP_SENSOR_ACC 1
65 #define MSP_SENSOR_BARO 2
66 #define MSP_SENSOR_MAG 4
67 #define MSP_SENSOR_GPS 8
69 #define MSP_API_VERSION 1
70 #define MSP_FC_VARIANT 2
71 #define MSP_FC_VERSION 3
72 #define MSP_BOARD_INFO 4
73 #define MSP_BUILD_INFO2 5 // clean/betaflight extension :( (MSP_BUILD_INFO had room for a 28-bit hash + up to 36-bit time already!)
75 #define MSP_FEATURE 36
76 #define MSP_CONFIG 66 // baseflight
77 #define MSP_BUILD_INFO 69 // baseflight
78 #define MSP_IDENT 100 // multitype + multiwii version + protocol version + capability variable
79 #define MSP_STATUS 101 // cycletime & errors_count & sensor present & box activation & current setting number
80 #define MSP_RAW_IMU 102 // 9 DOF
81 #define MSP_SERVO 103 // 8 servos
82 #define MSP_MOTOR 104 // 8 motors
83 #define MSP_RC 105 // 8 rc chan and more
84 #define MSP_RAW_GPS 106 // fix, numsat, lat, lon, alt, speed, ground course
85 #define MSP_COMP_GPS 107 // distance home, direction home
86 #define MSP_ATTITUDE 108 // 2 angles 1 heading
87 #define MSP_ALTITUDE 109 // altitude, variometer
88 #define MSP_ANALOG 110 // vbat, powermetersum, rssi if available on RX
89 #define MSP_RC_TUNING 111 // rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID
90 #define MSP_PID 112 // P I D coeff (9 are used currently)
91 #define MSP_BOX 113 // BOX setup (number is dependant of your setup)
92 #define MSP_MISC 114 // powermeter trig
93 #define MSP_MOTOR_PINS 115 // which pins are in use for motors & servos, for GUI
94 #define MSP_BOXNAMES 116 // the aux switch names
95 #define MSP_PIDNAMES 117 // the PID names
96 #define MSP_BOXIDS 119 // get the permanent IDs associated to BOXes
97 #define MSP_NAV_STATUS 121 // Returns navigation status
98 #define MSP_CELLS 130 // FrSky SPort Telemtry
99 #define MSP_UID 160 // Hardware serial number
100 #define MSP_SET_PID 202
101 #define MSP_ALARMS 242 // Alarm request
102 #define MSP_SET_4WAY_IF 245 // Sets ESC serial interface
104 #define MSP_PROTOCOL_VERSION 0
105 #define MSP_API_VERSION_MAJOR 1
106 #define MSP_API_VERSION_MINOR 31 // Matches 3.1.6
114 enum msp_vehicle_type {
115 MSP_MULTITYPE_TRI = 1,
116 MSP_MULTITYPE_QUADP = 2,
117 MSP_MULTITYPE_QUADX = 3,
118 MSP_MULTITYPE_BI = 4,
119 MSP_MULTITYPE_GIMBAL = 5,
120 MSP_MULTITYPE_Y6 = 6,
121 MSP_MULTITYPE_HEX6 = 7,
122 MSP_MULTITYPE_FLYING_WING = 8,
123 MSP_MULTITYPE_Y4 = 9,
124 MSP_MULTITYPE_HEX6X = 10,
125 MSP_MULTITYPE_OCTOX8 = 11,
126 MSP_MULTITYPE_OCTOFLATP = 12,
127 MSP_MULTITYPE_OCTOFLATX = 13,
128 MSP_MULTITYPE_AIRPLANE = 14,
129 MSP_MULTITYPE_HELI_120_CCPM = 15,
130 MSP_MULTITYPE_HELI_90_DEG = 16,
131 MSP_MULTITYPE_VTAIL4 = 17,
132 MSP_MULTITYPE_HEX6H = 18,
133 MSP_MULTITYPE_PPM_TO_SERVO = 19,
134 MSP_MULTITYPE_DUALCOPTER = 20,
135 MSP_MULTITYPE_SINGLECOPTER = 21,
136 MSP_MULTITYPE_ATAIL4 = 22,
137 MSP_MULTITYPE_CUSTOM = 23,
138 MSP_MULTITYPE_CUSTOM_PLANE = 24,
153 const static struct {
156 FlightStatusFlightModeOptions tlmode;
158 { MSP_BOX_ARM, 0, 0 },
159 { MSP_BOX_ANGLE, 1, FLIGHTSTATUS_FLIGHTMODE_LEVELING},
160 { MSP_BOX_HORIZON, 2, FLIGHTSTATUS_FLIGHTMODE_HORIZON},
161 { MSP_BOX_BARO, 3, FLIGHTSTATUS_FLIGHTMODE_ALTITUDEHOLD},
162 { MSP_BOX_VARIO, 4, 0},
163 { MSP_BOX_MAG, 5, 0},
164 { MSP_BOX_GPSHOME, 10, FLIGHTSTATUS_FLIGHTMODE_RETURNTOHOME},
165 { MSP_BOX_GPSHOLD, 11, FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD},
166 { MSP_BOX_LAST, 0xff, 0},
187 PROTOCOL_KISSALL = 3,
189 PROTOCOL_4WAY = 0xff,
192 struct msp_cmddata_escserial {
193 msp_esc_protocol protocol;
209 struct msp_cmddata_escserial escserial;
213 #if defined(PIOS_MSP_STACK_SIZE)
214 #define STACK_SIZE_BYTES PIOS_MSP_STACK_SIZE
216 #define STACK_SIZE_BYTES 1500
218 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
220 #define MAX_ALARM_LEN 30
222 #define BOOT_DISPLAY_TIME_MS (10*1000)
227 static int32_t uavoMSPBridgeInitialize(
void);
228 static void uavoMSPBridgeTask(
void *parameters);
232 static void msp_send_error(
struct msp_bridge *m, uint8_t
cmd)
246 static void msp_send(
struct msp_bridge *m, uint8_t
cmd,
const uint8_t *
data,
size_t len)
249 uint8_t cs = (uint8_t)(len) ^
cmd;
254 buf[3] = (uint8_t)(len);
260 for (
int i = 0;
i < len;
i++) {
273 return MSP_HEADER_CMD;
280 m->checksum ^= m->cmd_id;
282 if (m->cmd_size >
sizeof(m->cmd_data)) {
287 return m->cmd_size == 0 ? MSP_CHECKSUM : MSP_FILLBUF;
292 m->cmd_data.data[m->cmd_i++] = b;
294 return m->cmd_i == m->cmd_size ? MSP_CHECKSUM : MSP_FILLBUF;
297 static void msp_send_name(
struct msp_bridge *m)
299 const char hardcoded_name[] =
"dRonin";
301 msp_send(m, MSP_NAME, (uint8_t *) hardcoded_name, strlen(hardcoded_name));
304 static void msp_send_motor(
struct msp_bridge *m)
312 memset(&data, 0,
sizeof(data));
314 msp_send(m, MSP_MOTOR, data.buf,
sizeof(data));
317 static void msp_send_feature(
struct msp_bridge *m)
324 #define FEATURE_TELEMETRY (1 << 10)
325 data.features = FEATURE_TELEMETRY;
327 msp_send(m, MSP_FEATURE, data.buf,
sizeof(data));
330 static void msp_send_misc(
struct msp_bridge *m)
347 memset(&data, 0,
sizeof(data));
349 data.fc_misc.mid_rc = 1500;
350 data.fc_misc.min_command = 1000;
351 data.fc_misc.min_throt = 1150;
352 data.fc_misc.max_throt = 2000;
354 msp_send(m, MSP_MISC, data.buf,
sizeof(data));
357 static void msp_send_fc_version(
struct msp_bridge *m)
369 data.fc_ver.major = 1;
370 data.fc_ver.minor = 0;
371 data.fc_ver.patch = 0;
373 msp_send(m, MSP_FC_VERSION, data.buf,
sizeof(data));
376 static void msp_send_fc_variant(
struct msp_bridge *m)
385 memset(&data, 0,
sizeof(data));
387 memcpy(data.var.name,
"DRON", 4);
389 msp_send(m, MSP_FC_VARIANT, data.buf,
sizeof(data));
392 static void msp_send_board_info(
struct msp_bridge *m)
402 memset(&data, 0,
sizeof(data));
404 memcpy(data.board.name, DRONIN_TARGET,
MIN(4, strlen(DRONIN_TARGET)));
406 msp_send(m, MSP_BOARD_INFO, data.buf,
sizeof(data));
409 static void msp_send_config(
struct msp_bridge *m)
414 uint8_t mixer_config;
418 uint16_t align_pitch;
420 uint16_t current_scale;
421 uint16_t current_offset;
422 uint16_t motor_pwm_rate;
424 uint8_t power_adc_channel;
431 memset(&data, 0, sizeof(data));
433 data.config.locked_in = 1;
435 msp_send(m, MSP_CONFIG, data.buf, sizeof(data));
438 static
void msp_send_build_info(struct
msp_bridge *m)
448 memset(&data, 0,
sizeof(data));
452 msp_send(m, MSP_BUILD_INFO, data.buf,
sizeof(data));
455 static void msp_send_build_info_cf(
struct msp_bridge *m)
466 memset(&data, 0,
sizeof(data));
470 msp_send(m, MSP_BUILD_INFO2, data.buf,
sizeof(data));
475 static void msp_send_uid(
struct msp_bridge *m)
486 msp_send(m, MSP_UID, data.buf,
sizeof(data));
489 static void msp_send_api_version(
struct msp_bridge *m)
494 uint8_t protocol_ver;
495 uint8_t api_version_major;
496 uint8_t api_version_minor;
500 data.ident.protocol_ver = MSP_PROTOCOL_VERSION;
501 data.ident.api_version_major = MSP_API_VERSION_MAJOR;
502 data.ident.api_version_minor = MSP_API_VERSION_MINOR;
504 msp_send(m, MSP_API_VERSION, data.buf,
sizeof(data));
507 static void msp_send_attitude(
struct msp_bridge *m)
517 AttitudeActualData attActual;
519 AttitudeActualGet(&attActual);
522 data.att.x = attActual.Roll * 10;
523 data.att.y = attActual.Pitch * -10;
525 data.att.h = attActual.Yaw;
527 msp_send(m, MSP_ATTITUDE, data.buf,
sizeof(data));
530 static void msp_send_ident(
struct msp_bridge *m)
535 uint8_t multiwii_version;
536 uint8_t vehicle_type;
538 uint32_t capabilities;
542 data.ident.multiwii_version = 255;
544 data.ident.capabilities = 0x80000004;
547 SystemSettingsAirframeTypeGet(&type);
549 case SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWING:
550 data.ident.vehicle_type = MSP_MULTITYPE_AIRPLANE;
552 case SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGELEVON:
553 data.ident.vehicle_type = MSP_MULTITYPE_FLYING_WING;
555 case SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGVTAIL:
556 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM_PLANE;
558 case SYSTEMSETTINGS_AIRFRAMETYPE_VTOL:
559 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
561 case SYSTEMSETTINGS_AIRFRAMETYPE_HELICP:
562 data.ident.vehicle_type = MSP_MULTITYPE_HELI_120_CCPM;
564 case SYSTEMSETTINGS_AIRFRAMETYPE_QUADX:
565 data.ident.vehicle_type = MSP_MULTITYPE_QUADX;
567 case SYSTEMSETTINGS_AIRFRAMETYPE_QUADP:
568 data.ident.vehicle_type = MSP_MULTITYPE_QUADP;
570 case SYSTEMSETTINGS_AIRFRAMETYPE_HEXA:
571 data.ident.vehicle_type = MSP_MULTITYPE_HEX6H;
573 case SYSTEMSETTINGS_AIRFRAMETYPE_OCTO:
574 data.ident.vehicle_type = MSP_MULTITYPE_OCTOFLATX;
576 case SYSTEMSETTINGS_AIRFRAMETYPE_CUSTOM:
577 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
579 case SYSTEMSETTINGS_AIRFRAMETYPE_HEXAX:
580 data.ident.vehicle_type = MSP_MULTITYPE_HEX6X;
582 case SYSTEMSETTINGS_AIRFRAMETYPE_OCTOV:
583 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
585 case SYSTEMSETTINGS_AIRFRAMETYPE_OCTOCOAXP:
586 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
588 case SYSTEMSETTINGS_AIRFRAMETYPE_OCTOCOAXX:
589 data.ident.vehicle_type = MSP_MULTITYPE_OCTOX8;
591 case SYSTEMSETTINGS_AIRFRAMETYPE_HEXACOAX:
592 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
594 case SYSTEMSETTINGS_AIRFRAMETYPE_TRI:
595 data.ident.vehicle_type = MSP_MULTITYPE_TRI;
597 case SYSTEMSETTINGS_AIRFRAMETYPE_GROUNDVEHICLECAR:
598 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
600 case SYSTEMSETTINGS_AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL:
601 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
603 case SYSTEMSETTINGS_AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE:
604 data.ident.vehicle_type = MSP_MULTITYPE_CUSTOM;
608 msp_send(m, MSP_IDENT, data.buf,
sizeof(data));
611 static void msp_send_rc_tuning(
struct msp_bridge *m)
618 uint8_t _roll_pitch_rate;
620 uint8_t dyn_throttle_pid;
626 memset(&data, 0, sizeof(data));
628 msp_send(m, MSP_RC_TUNING, data.buf, sizeof(data));
631 #define PID_SCALE_KP 10000.0f
632 #define PID_SCALE_KI 1000.0f
633 #define PID_SCALE_KD 1000000.0f
645 struct set_pid *data = (struct set_pid *)m->cmd_data.data;
648 FlightStatusArmedGet(&armed);
650 if (sizeof(*data) > m->cmd_i || armed != FLIGHTSTATUS_ARMED_DISARMED)
651 msp_send_error(m, MSP_SET_PID);
653 StabilizationSettingsData stab;
654 StabilizationSettingsGet(&stab);
656 #define SCALE_PID_DR(axisnum, pid) ((float)data->axis[axisnum].pid / PID_SCALE_K##pid)
658 stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KP] = SCALE_PID_DR(0,
P);
659 stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KI] = SCALE_PID_DR(0, I);
660 stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KD] = SCALE_PID_DR(0, D);
661 stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KP] = SCALE_PID_DR(1,
P);
662 stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KI] = SCALE_PID_DR(1, I);
663 stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KD] = SCALE_PID_DR(1, D);
664 stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KP] = SCALE_PID_DR(2,
P);
665 stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KI] = SCALE_PID_DR(2, I);
666 stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KD] = SCALE_PID_DR(2, D);
668 StabilizationSettingsSet(&stab);
670 msp_send(m, MSP_SET_PID, NULL, 0);
673 static void msp_send_pid(
struct msp_bridge *m)
686 memset(&data, 0, sizeof(data));
688 StabilizationSettingsData stab;
689 StabilizationSettingsGet(&stab);
691 #define SCALE_PID_MW(axis, axisu, pid) bound_min_max( \
692 stab.axis##RatePID[STABILIZATIONSETTINGS_##axisu##RATEPID_K##pid] \
693 * PID_SCALE_K##pid, 0.0f, 255.0f)
695 data.pid.axis[0].
p = SCALE_PID_MW(Roll,
ROLL,
P);
696 data.pid.axis[0].i = SCALE_PID_MW(Roll,
ROLL, I);
697 data.pid.axis[0].d = SCALE_PID_MW(Roll,
ROLL, D);
698 data.pid.axis[1].p = SCALE_PID_MW(Pitch,
PITCH,
P);
699 data.pid.axis[1].i = SCALE_PID_MW(Pitch,
PITCH, I);
700 data.pid.axis[1].d = SCALE_PID_MW(Pitch,
PITCH, D);
701 data.pid.axis[2].p = SCALE_PID_MW(Yaw,
YAW,
P);
702 data.pid.axis[2].i = SCALE_PID_MW(Yaw,
YAW, I);
703 data.pid.axis[2].d = SCALE_PID_MW(Yaw,
YAW, D);
705 msp_send(m, MSP_PID, data.buf,
sizeof(data));
708 static void msp_send_pid_names(
struct msp_bridge *m)
710 const char names[] =
"ROLL;PITCH;YAW;";
711 msp_send(m, MSP_PIDNAMES, (
const uint8_t *)names,
sizeof(names));
714 static void msp_send_status(
struct msp_bridge *m)
728 ActuatorDesiredUpdateTimeGet(&cycle_time);
729 data.status.cycleTime = cycle_time * 1000;
731 data.status.i2cErrors = 0;
733 GPSPositionData gpsData = {};
735 if (GPSPositionHandle() != NULL)
736 GPSPositionGet(&gpsData);
741 (gpsData.Status != GPSPOSITION_STATUS_NOGPS ? MSP_SENSOR_GPS : 0);
743 data.status.flags = 0;
744 data.status.setting = 0;
746 if (FlightStatusHandle() != NULL) {
747 FlightStatusData flight_status;
748 FlightStatusGet(&flight_status);
750 data.status.flags = flight_status.Armed == FLIGHTSTATUS_ARMED_ARMED;
752 for (
int i = 1; msp_boxes[
i].mode != MSP_BOX_LAST;
i++) {
753 if (flight_status.FlightMode == msp_boxes[
i].tlmode) {
754 data.status.flags |= (1 <<
i);
759 msp_send(m, MSP_STATUS, data.buf,
sizeof(data));
762 static void msp_send_analog(
struct msp_bridge *m)
768 uint16_t powerMeterSum;
773 data.status.powerMeterSum = 0;
775 FlightBatterySettingsData batSettings = {};
776 FlightBatteryStateData batState = {};
778 if (FlightBatteryStateHandle() != NULL)
779 FlightBatteryStateGet(&batState);
780 if (FlightBatterySettingsHandle() != NULL) {
781 FlightBatterySettingsGet(&batSettings);
784 if (batSettings.VoltagePin != FLIGHTBATTERYSETTINGS_VOLTAGEPIN_NONE)
785 data.status.vbat = (uint8_t)lroundf(batState.Voltage * 10);
787 if (batSettings.CurrentPin != FLIGHTBATTERYSETTINGS_CURRENTPIN_NONE) {
788 data.status.current = lroundf(batState.Current * 100);
789 data.status.powerMeterSum = lroundf(batState.ConsumedEnergy);
792 ManualControlCommandData manualState;
793 ManualControlCommandGet(&manualState);
796 if (manualState.Rssi <= 0) {
797 data.status.rssi = 0;
798 }
else if (manualState.Rssi >= 100) {
799 data.status.rssi = 1023;
801 data.status.rssi = manualState.Rssi * 10;
804 msp_send(m, MSP_ANALOG, data.buf,
sizeof(data));
807 static void msp_send_raw_gps(
struct msp_bridge *m)
822 GPSPositionData gps_data = {};
824 if (GPSPositionHandle() != NULL)
826 GPSPositionGet(&gps_data);
827 data.raw_gps.fix = (gps_data.Status >= GPSPOSITION_STATUS_FIX2D ? 1 : 0);
828 data.raw_gps.num_sat = gps_data.Satellites;
829 data.raw_gps.lat = gps_data.Latitude;
830 data.raw_gps.lon = gps_data.Longitude;
831 data.raw_gps.alt = (uint16_t)gps_data.Altitude;
832 data.raw_gps.speed = (uint16_t)(gps_data.Groundspeed * 100.0f);
833 data.raw_gps.ground_course = (int16_t)(gps_data.Heading * 10.0f);
837 data.raw_gps.fix = 0;
838 data.raw_gps.num_sat = 0;
839 data.raw_gps.lat = 0;
840 data.raw_gps.lon = 0;
841 data.raw_gps.alt = 0;
842 data.raw_gps.speed = 0;
843 data.raw_gps.ground_course = 0;
846 msp_send(m, MSP_RAW_GPS, data.buf,
sizeof(data));
849 static void msp_send_comp_gps(
struct msp_bridge *m)
856 uint8_t home_position_valid;
860 GPSPositionData gps_data = {};
861 HomeLocationData home_data = {};
863 if ((GPSPositionHandle() == NULL) || (HomeLocationHandle() == NULL))
865 data.comp_gps.distance_to_home = 0;
866 data.comp_gps.direction_to_home = 0;
867 data.comp_gps.home_position_valid = 0;
871 GPSPositionGet(&gps_data);
872 HomeLocationGet(&home_data);
874 if((gps_data.Status < GPSPOSITION_STATUS_FIX2D) || (home_data.Set == HOMELOCATION_SET_FALSE))
876 data.comp_gps.distance_to_home = 0;
877 data.comp_gps.direction_to_home = 0;
878 data.comp_gps.home_position_valid = 0;
882 data.comp_gps.home_position_valid = 1;
884 int32_t delta_lon = (home_data.Longitude - gps_data.Longitude);
885 int32_t delta_lat = (home_data.Latitude - gps_data.Latitude );
887 float delta_y = (float)delta_lon * WGS84_RADIUS_EARTH_KM * DEG2RAD;
888 float delta_x = (float)delta_lat * WGS84_RADIUS_EARTH_KM * DEG2RAD;
890 delta_y *= cosf((
float)home_data.Latitude * 1e-7
f * (
float)DEG2RAD);
892 data.comp_gps.distance_to_home = (uint16_t)(sqrtf(delta_x * delta_x + delta_y * delta_y) * 1e-4
f);
894 if ((delta_lon == 0) && (delta_lat == 0))
895 data.comp_gps.direction_to_home = 0;
897 data.comp_gps.direction_to_home = (int16_t)(atan2f(delta_y, delta_x) * RAD2DEG);
901 msp_send(m, MSP_COMP_GPS, data.buf,
sizeof(data));
904 static void msp_send_altitude(
struct msp_bridge *m)
916 if (PositionActualHandle() != NULL) {
917 PositionActualDownGet(&tmp);
923 data.baro.alt = (int32_t)roundf(tmp * 100.0
f);
925 msp_send(m, MSP_ALTITUDE, data.buf,
sizeof(data));
930 static uint16_t msp_scale_rc(
float percent) {
931 return percent*500 + 1500;
939 static uint16_t msp_scale_rc_thr(
float percent) {
940 return percent <= 0 ? 1100 : percent*800 + 1100;
944 static void msp_send_channels(
struct msp_bridge *m)
946 ManualControlCommandData manualState;
947 ManualControlCommandGet(&manualState);
951 uint16_t channels[8];
954 msp_scale_rc(manualState.Roll),
955 msp_scale_rc(manualState.Pitch * -1),
956 msp_scale_rc(manualState.Yaw),
957 msp_scale_rc_thr(manualState.Throttle),
958 msp_scale_rc(manualState.Accessory[0]),
959 msp_scale_rc(manualState.Accessory[1]),
960 msp_scale_rc(manualState.Accessory[2]),
965 msp_send(m, MSP_RC, data.buf,
sizeof(data));
968 static void msp_send_boxids(
struct msp_bridge *m) {
969 uint8_t boxes[MSP_BOX_LAST];
972 for (
int i = 0; msp_boxes[
i].mode != MSP_BOX_LAST;
i++) {
973 boxes[len++] = msp_boxes[
i].mwboxid;
975 msp_send(m, MSP_BOXIDS, boxes, len);
978 #ifdef PIOS_INCLUDE_4WAY
982 static void msp_handle_4wif(
struct msp_bridge *m) {
983 struct msp_cmddata_escserial *escserial = &m->cmd_data.escserial;
987 msp_esc_protocol protocol = PROTOCOL_4WAY;
989 if (m->cmd_size >=
sizeof(*escserial)) {
990 protocol = escserial->protocol;
995 #ifdef PIOS_INCLUDE_4WAY
1003 m->handler = MSP_HANDLER_4WIF;
1007 case PROTOCOL_SIMONK:
1008 case PROTOCOL_BLHELI:
1010 case PROTOCOL_KISSALL:
1011 case PROTOCOL_CASTLE:
1017 msp_send(m, MSP_SET_4WAY_IF, &num_esc, 1);
1021 #define ALARM_WARN 1
1022 #define ALARM_ERROR 2
1023 #define ALARM_CRIT 3
1025 static void msp_send_alarms(
struct msp_bridge *m) {
1034 SystemAlarmsData alarm;
1035 SystemAlarmsGet(&alarm);
1039 data.alarm.state = ALARM_CRIT;
1043 msp_send(m, MSP_ALARMS, data.buf, strlen((
char*)data.alarm.msg)+1);
1048 data.alarm.state = ALARM_OK;
1050 sizeof(data.alarm.msg),
false, &
state);
1052 case SYSTEMALARMS_ALARM_WARNING:
1053 data.alarm.state = ALARM_WARN;
1055 case SYSTEMALARMS_ALARM_ERROR:
1057 case SYSTEMALARMS_ALARM_CRITICAL:
1058 data.alarm.state = ALARM_CRIT;;
1061 msp_send(m, MSP_ALARMS, data.buf, len+1);
1066 if ((m->checksum ^ b) != 0) {
1071 switch (m->cmd_id) {
1072 case MSP_API_VERSION:
1073 msp_send_api_version(m);
1075 case MSP_FC_VERSION:
1076 msp_send_fc_version(m);
1078 case MSP_FC_VARIANT:
1079 msp_send_fc_variant(m);
1081 case MSP_BOARD_INFO:
1082 msp_send_board_info(m);
1084 case MSP_BUILD_INFO2:
1085 msp_send_build_info_cf(m);
1091 msp_send_feature(m);
1096 case MSP_BUILD_INFO:
1097 msp_send_build_info(m);
1109 msp_send_raw_gps(m);
1112 msp_send_comp_gps(m);
1115 msp_send_altitude(m);
1118 msp_send_attitude(m);
1127 msp_send_channels(m);
1130 msp_send_rc_tuning(m);
1142 msp_send_pid_names(m);
1150 case MSP_SET_4WAY_IF:
1154 msp_send_error(m, m->cmd_id);
1162 return m->cmd_i++ == m->cmd_size ? MSP_IDLE : MSP_DISCARD;
1170 static void msp_receive_byte(
struct msp_bridge *m, uint8_t b)
1176 m->state = MSP_MAYBE_UAVTALK2;
1179 m->state = MSP_HEADER_START;
1182 m->state = MSP_IDLE;
1185 case MSP_HEADER_START:
1186 m->state = b ==
'M' ? MSP_HEADER_M : MSP_IDLE;
1189 m->state = b ==
'<' ? MSP_HEADER_SIZE : MSP_IDLE;
1191 case MSP_HEADER_SIZE:
1192 m->state = msp_state_size(m, b);
1194 case MSP_HEADER_CMD:
1195 m->state = msp_state_cmd(m, b);
1198 m->state = msp_state_fill_buf(m, b);
1201 m->state = msp_state_checksum(m, b);
1204 m->state = msp_state_discard(m, b);
1206 case MSP_MAYBE_UAVTALK2:
1209 m->state = (b&0xf0) == 0x20 ? MSP_MAYBE_UAVTALK3 : MSP_IDLE;
1211 case MSP_MAYBE_UAVTALK3:
1213 m->state = MSP_MAYBE_UAVTALK4;
1215 case MSP_MAYBE_UAVTALK4:
1216 m->state = MSP_IDLE;
1218 if ((b & 0xf0) == 0) {
1221 m->handler = MSP_HANDLER_IDLE;
1231 static int32_t uavoMSPBridgeStart(
void)
1233 if (!module_enabled) {
1243 uavoMSPBridgeTask,
"uavoMSPBridge",
1251 static void setMSPSpeed(
struct msp_bridge *m)
1255 ModuleSettingsMSPSpeedGet(&speed);
1265 static int32_t uavoMSPBridgeInitialize(
void)
1270 memset(msp, 0x00,
sizeof(*msp));
1274 module_enabled =
true;
1289 static
void uavoMSPBridgeTask(
void *parameters)
1294 switch (msp->handler) {
1295 case MSP_HANDLER_MSP:
1304 msp_receive_byte(msp, b);
1309 #ifdef PIOS_INCLUDE_4WAY
1310 case MSP_HANDLER_4WIF:
1312 msp->handler = MSP_HANDLER_MSP;
1319 case MSP_HANDLER_IDLE:
1333 #endif //PIOS_INCLUDE_MSP_BRIDGE
static bool msp_handler(enum msp_message_id msg_id, void *data, uint8_t len, void *context)
uint32_t PIOS_Thread_Systime(void)
uint16_t direction_to_home
uint8_t esc4wayInit(void)
struct usb_configuration_desc config
static struct GPSGlobals * gps
bool PIOS_Modules_IsEnabled(enum pios_modules module)
struct pios_com_dev * com
void * PIOS_malloc(size_t size)
#define PIOS_SYS_SERIAL_NUM_BINARY_LEN
static struct msp_bridge * msp
void PIOS_HAL_ConfigureSerialSpeed(uintptr_t com_id, HwSharedSpeedBpsOptions speed)
uint8_t data[XFER_BYTES_PER_PACKET]
#define PIOS_COM_TELEM_SER
bool PIOS_SENSORS_IsRegistered(enum pios_sensor_type type)
Checks if a sensor type is registered with the PIOS_SENSORS interface.
#define MODULE_INITCALL(ifn, sfn)
uint16_t PIOS_COM_ReceiveBuffer(uintptr_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms)
#define BOOT_DISPLAY_TIME_MS
static struct PIOS_Sensor sensors[PIOS_SENSOR_NUM]
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
static TaskInfoRunningElem task
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
const char * AlarmBootReason(uint8_t reason)
uint16_t distance_to_home
void PIOS_Thread_Sleep(uint32_t time_ms)
PIOS_COM_SendBuffer(shub_global->frsky_port, shub_global->serial_buf, msg_length)
void esc4wayProcess(struct serialPort_s *mspPort)
#define DONT_BUILD_IF(COND, MSG)
Includes PiOS and core architecture components.
uintptr_t pios_com_msp_id
Generic interface for sensors.
int32_t AlarmString(SystemAlarmsData *alarm, char *buf, size_t buflen, bool blink, uint8_t *state)
if(BaroAltitudeHandle()!=NULL)
static ManualControlCommandData cmd
#define PIOS_Assert(test)
int32_t PIOS_SYS_SerialNumberGetBinary(uint8_t array[PIOS_SYS_SERIAL_NUM_BINARY_LEN])