2 output MSP protocol from AP_Periph for ArduPilot and INAV
3 Thanks to input from Konstantin Sharlaimov
6 #include <AP_HAL/AP_HAL_Boards.h>
9 #ifdef HAL_PERIPH_ENABLE_MSP
11 void AP_Periph_FW::msp_init(AP_HAL::UARTDriver
*_uart
)
14 msp
.port
.uart
= _uart
;
15 msp
.port
.msp_version
= MSP::MSP_V2_NATIVE
;
16 _uart
->begin(115200, 512, 512);
24 void AP_Periph_FW::send_msp_packet(uint16_t cmd
, void *p
, uint16_t size
)
26 uint8_t out_buf
[size
+16] {};
27 MSP::msp_packet_t pkt
= {
28 .buf
= { .ptr
= out_buf
, .end
= MSP_ARRAYEND(out_buf
), },
34 sbuf_write_data(&pkt
.buf
, p
, size
);
35 sbuf_switch_to_reader(&pkt
.buf
, &out_buf
[0]);
37 MSP::msp_serial_encode(&msp
.port
, &pkt
, MSP::MSP_V2_NATIVE
, true);
43 void AP_Periph_FW::msp_sensor_update(void)
45 if (msp
.port
.uart
== nullptr) {
48 #if AP_PERIPH_GPS_ENABLED
51 #if AP_PERIPH_BARO_ENABLED
54 #if AP_PERIPH_MAG_ENABLED
57 #ifdef HAL_PERIPH_ENABLE_AIRSPEED
63 #if AP_PERIPH_GPS_ENABLED
67 void AP_Periph_FW::send_msp_GPS(void)
69 MSP::msp_gps_data_message_t p
;
71 if (gps
.get_type(0) == AP_GPS::GPS_Type::GPS_TYPE_NONE
) {
74 if (msp
.last_gps_ms
== gps
.last_message_time_ms(0)) {
77 msp
.last_gps_ms
= gps
.last_message_time_ms(0);
79 const Location
&loc
= gps
.location(0);
80 const Vector3f
&vel
= gps
.velocity(0);
83 p
.gps_week
= gps
.time_week(0);
84 p
.ms_tow
= gps
.get_itow(0);
85 p
.fix_type
= uint8_t(gps
.status(0));
86 p
.satellites_in_view
= gps
.num_sats(0);
88 float hacc
=0, vacc
=0, sacc
=0;
89 gps
.horizontal_accuracy(0, hacc
);
90 gps
.vertical_accuracy(0, vacc
);
91 gps
.speed_accuracy(0, sacc
);
93 p
.horizontal_vel_accuracy
= sacc
*100;
94 p
.horizontal_pos_accuracy
= hacc
*100;
95 p
.vertical_pos_accuracy
= vacc
*100;
96 p
.hdop
= gps
.get_hdop(0);
97 p
.longitude
= loc
.lng
;
99 p
.msl_altitude
= loc
.alt
;
100 p
.ned_vel_north
= vel
.x
*100;
101 p
.ned_vel_east
= vel
.y
*100;
102 p
.ned_vel_down
= vel
.z
*100;
103 p
.ground_course
= wrap_360_cd(gps
.ground_course(0)*100);
104 float yaw_deg
=0, acc
;
106 if (gps
.gps_yaw_deg(0, yaw_deg
, acc
, time_ms
)) {
107 p
.true_yaw
= wrap_360_cd(yaw_deg
*100);
109 p
.true_yaw
= 65535; // unknown
111 uint64_t tepoch_us
= gps
.time_epoch_usec(0);
112 time_t utc_sec
= tepoch_us
/ (1000U * 1000U);
114 struct tm
* tm
= gmtime_r(&utc_sec
, &tvd
);
116 p
.year
= tm
->tm_year
+1900;
117 p
.month
= tm
->tm_mon
;
119 p
.hour
= tm
->tm_hour
;
123 send_msp_packet(MSP2_SENSOR_GPS
, &p
, sizeof(p
));
125 #endif // AP_PERIPH_GPS_ENABLED
128 #if AP_PERIPH_BARO_ENABLED
132 void AP_Periph_FW::send_msp_baro(void)
134 MSP::msp_baro_data_message_t p
;
136 if (msp
.last_baro_ms
== baro
.get_last_update(0)) {
139 if (!baro
.healthy()) {
140 // don't send any data
143 msp
.last_baro_ms
= baro
.get_last_update(0);
146 p
.time_ms
= msp
.last_baro_ms
;
147 p
.pressure_pa
= baro
.get_pressure();
148 p
.temp
= baro
.get_temperature() * 100;
150 send_msp_packet(MSP2_SENSOR_BAROMETER
, &p
, sizeof(p
));
152 #endif // AP_PERIPH_BARO_ENABLED
154 #if AP_PERIPH_MAG_ENABLED
156 send MSP compass packet
158 void AP_Periph_FW::send_msp_compass(void)
160 MSP::msp_compass_data_message_t p
;
162 if (msp
.last_mag_ms
== compass
.last_update_ms(0)) {
165 if (!compass
.healthy()) {
168 msp
.last_mag_ms
= compass
.last_update_ms(0);
170 const Vector3f
&field
= compass
.get_field(0);
172 p
.time_ms
= msp
.last_mag_ms
;
177 send_msp_packet(MSP2_SENSOR_COMPASS
, &p
, sizeof(p
));
179 #endif // AP_PERIPH_MAG_ENABLED
181 #ifdef HAL_PERIPH_ENABLE_AIRSPEED
183 send MSP airspeed packet
185 void AP_Periph_FW::send_msp_airspeed(void)
187 MSP::msp_airspeed_data_message_t p
;
189 const uint32_t last_update_ms
= airspeed
.last_update_ms();
190 if (msp
.last_airspeed_ms
== last_update_ms
) {
193 if (!airspeed
.healthy()) {
194 // we don't report at all for an unhealthy sensor. This maps
195 // to unhealthy in the flight controller driver
198 msp
.last_airspeed_ms
= last_update_ms
;
201 p
.time_ms
= msp
.last_airspeed_ms
;
202 p
.pressure
= airspeed
.get_corrected_pressure();
204 if (!airspeed
.get_temperature(temp
)) {
205 p
.temp
= INT16_MIN
; //invalid temperature
210 send_msp_packet(MSP2_SENSOR_AIRSPEED
, &p
, sizeof(p
));
212 #endif // HAL_PERIPH_ENABLE_AIRSPEED
215 #endif // HAL_PERIPH_ENABLE_MSP