@ -9,6 +9,16 @@
@@ -9,6 +9,16 @@
# include <AP_RangeFinder/AP_RangeFinder.h>
# include <GCS_MAVLink/GCS.h>
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
# include <AC_Fence/AC_Fence.h>
# include <AP_Logger/AP_Logger.h>
# include <AP_Param/AP_Param.h>
# include <AP_Vehicle/AP_Vehicle.h>
# include <SRV_Channel/SRV_Channel.h>
# include <stdio.h>
# include "AP_Frsky_MAVlite.h"
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
/*
for FrSky SPort Passthrough
*/
@ -99,12 +109,50 @@ void AP_Frsky_SPort_Passthrough::setup_wfq_scheduler(void)
@@ -99,12 +109,50 @@ void AP_Frsky_SPort_Passthrough::setup_wfq_scheduler(void)
set_scheduler_entry ( GPS_STATUS , 700 , 500 ) ; // 0x5002 GPS status
set_scheduler_entry ( HOME , 400 , 500 ) ; // 0x5004 Home
set_scheduler_entry ( BATT_2 , 1300 , 500 ) ; // 0x5008 Battery 2 status
set_scheduler_entry ( BATT_1 , 1300 , 500 ) ; // 0x5008 Battery 1 status
set_scheduler_entry ( BATT_1 , 1300 , 500 ) ; // 0x5003 Battery 1 status
set_scheduler_entry ( PARAM , 1700 , 1000 ) ; // 0x5007 parameters
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
set_scheduler_entry ( MAV , 35 , 25 ) ; // mavlite
// initialize sport sensor IDs
set_sensor_id ( _frsky_parameters - > _uplink_id , _SPort_bidir . uplink_sensor_id ) ;
set_sensor_id ( _frsky_parameters - > _dnlink1_id , _SPort_bidir . downlink1_sensor_id ) ;
set_sensor_id ( _frsky_parameters - > _dnlink2_id , _SPort_bidir . downlink2_sensor_id ) ;
// initialize sport
hal . scheduler - > register_io_process ( FUNCTOR_BIND_MEMBER ( & AP_Frsky_SPort_Passthrough : : process_rx_queue , void ) ) ;
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
}
/*
dynamically change scheduler priorities based on queue sizes
*/
void AP_Frsky_SPort_Passthrough : : adjust_packet_weight ( bool queue_empty )
{
/*
When queues are empty set a low priority ( high weight ) , when queues
are not empty set a higher priority ( low weight ) based on the following
relative priority order : mavlite > status text > attitude .
*/
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
if ( ! _SPort_bidir . tx_packet_queue . is_empty ( ) ) {
_scheduler . packet_weight [ MAV ] = 30 ; // mavlite
if ( ! queue_empty ) {
_scheduler . packet_weight [ TEXT ] = 45 ; // messages
_scheduler . packet_weight [ ATTITUDE ] = 80 ; // attitude
} else {
_scheduler . packet_weight [ TEXT ] = 5000 ; // messages
_scheduler . packet_weight [ ATTITUDE ] = 80 ; // attitude
}
} else {
_scheduler . packet_weight [ MAV ] = 5000 ; // mavlite
if ( ! queue_empty ) {
_scheduler . packet_weight [ TEXT ] = 45 ; // messages
_scheduler . packet_weight [ ATTITUDE ] = 80 ; // attitude
} else {
_scheduler . packet_weight [ TEXT ] = 5000 ; // messages
_scheduler . packet_weight [ ATTITUDE ] = 45 ; // attitude
}
}
# else //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
if ( ! queue_empty ) {
_scheduler . packet_weight [ TEXT ] = 45 ; // messages
_scheduler . packet_weight [ ATTITUDE ] = 80 ; // attitude
@ -112,6 +160,7 @@ void AP_Frsky_SPort_Passthrough::adjust_packet_weight(bool queue_empty)
@@ -112,6 +160,7 @@ void AP_Frsky_SPort_Passthrough::adjust_packet_weight(bool queue_empty)
_scheduler . packet_weight [ TEXT ] = 5000 ; // messages
_scheduler . packet_weight [ ATTITUDE ] = 45 ; // attitude
}
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
}
// WFQ scheduler
@ -122,12 +171,22 @@ bool AP_Frsky_SPort_Passthrough::is_packet_ready(uint8_t idx, bool queue_empty)
@@ -122,12 +171,22 @@ bool AP_Frsky_SPort_Passthrough::is_packet_ready(uint8_t idx, bool queue_empty)
case TEXT :
packet_ready = ! queue_empty ;
break ;
case GPS_LAT :
case GPS_LON :
// force gps coords to use sensor 0x1B, always send when used with external data
packet_ready = _use_external_data | | ( _passthrough . new_byte = = SENSOR_ID_27 ) ;
break ;
case AP_STATUS :
packet_ready = gcs ( ) . vehicle_initialised ( ) ;
break ;
case BATT_2 :
packet_ready = AP : : battery ( ) . num_instances ( ) > 1 ;
break ;
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
case MAV :
packet_ready = ! _SPort_bidir . tx_packet_queue . is_empty ( ) ;
break ;
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
default :
packet_ready = true ;
break ;
@ -157,8 +216,7 @@ void AP_Frsky_SPort_Passthrough::process_packet(uint8_t idx)
@@ -157,8 +216,7 @@ void AP_Frsky_SPort_Passthrough::process_packet(uint8_t idx)
send_sport_frame ( SPORT_DATA_FRAME , GPS_LONG_LATI_FIRST_ID , calc_gps_latlng ( _passthrough . send_latitude ) ) ; // gps latitude or longitude
_passthrough . gps_lng_sample = calc_gps_latlng ( _passthrough . send_latitude ) ;
// force the scheduler to select GPS lon as packet that's been waiting the most
// this guarantees that gps coords are sent at max
// _scheduler.avg_polling_period*number_of_downlink_sensors time separation
// this guarantees that lat and lon are sent as consecutive packets
_scheduler . packet_timer [ GPS_LON ] = _scheduler . packet_timer [ GPS_LAT ] - 10000 ;
break ;
case GPS_LON : // 0x800 GPS lon
@ -185,6 +243,11 @@ void AP_Frsky_SPort_Passthrough::process_packet(uint8_t idx)
@@ -185,6 +243,11 @@ void AP_Frsky_SPort_Passthrough::process_packet(uint8_t idx)
case PARAM : // 0x5007 parameters
send_sport_frame ( SPORT_DATA_FRAME , DIY_FIRST_ID + 7 , calc_param ( ) ) ;
break ;
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
case MAV : // mavlite
process_tx_queue ( ) ;
break ;
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
}
}
@ -205,11 +268,17 @@ void AP_Frsky_SPort_Passthrough::send(void)
@@ -205,11 +268,17 @@ void AP_Frsky_SPort_Passthrough::send(void)
for ( uint16_t i = 0 ; i < numc ; i + + ) {
prev_byte = _passthrough . new_byte ;
_passthrough . new_byte = _port - > read ( ) ;
}
if ( prev_byte = = FRAME_HEAD ) {
if ( _passthrough . new_byte = = SENSOR_ID_27 ) { // byte 0x7E is the header of each poll request
run_wfq_scheduler ( ) ;
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
AP_Frsky_SPort : : sport_packet_t sp ;
if ( _sport_handler . process_byte ( sp , _passthrough . new_byte ) ) {
queue_rx_packet ( sp ) ;
}
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
}
// check if we should respond to this polling byte
if ( prev_byte = = FRAME_HEAD & & is_passthrough_byte ( _passthrough . new_byte ) ) {
run_wfq_scheduler ( ) ;
}
}
@ -358,6 +427,20 @@ uint32_t AP_Frsky_SPort_Passthrough::calc_batt(uint8_t instance)
@@ -358,6 +427,20 @@ uint32_t AP_Frsky_SPort_Passthrough::calc_batt(uint8_t instance)
return batt ;
}
/*
* true if we need to respond to the last polling byte
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
bool AP_Frsky_SPort_Passthrough : : is_passthrough_byte ( const uint8_t byte )
{
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
if ( byte = = _SPort_bidir . downlink1_sensor_id | | byte = = _SPort_bidir . downlink2_sensor_id ) {
return true ;
}
# endif
return byte = = SENSOR_ID_27 ;
}
/*
* prepare various autopilot status data
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
@ -465,6 +548,27 @@ uint32_t AP_Frsky_SPort_Passthrough::calc_attiandrng(void)
@@ -465,6 +548,27 @@ uint32_t AP_Frsky_SPort_Passthrough::calc_attiandrng(void)
return attiandrng ;
}
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
/*
allow external transports ( e . g . FPort ) , to supply telemetry data
*/
bool AP_Frsky_SPort_Passthrough : : set_telem_data ( const uint8_t frame , const uint16_t appid , const uint32_t data )
{
// queue only Uplink packets
if ( frame = = SPORT_UPLINK_FRAME | | frame = = SPORT_UPLINK_FRAME_RW ) {
const AP_Frsky_SPort : : sport_packet_t sp {
0x00 , // this is ignored by process_sport_rx_queue() so no need for a real sensor ID
frame ,
appid ,
data
} ;
_SPort_bidir . rx_packet_queue . push_force ( sp ) ;
return true ;
}
return false ;
}
/*
fetch Sport data for an external transport , such as FPort
*/
@ -545,3 +649,341 @@ uint16_t AP_Frsky_SPort_Passthrough::prep_number(int32_t number, uint8_t digits,
@@ -545,3 +649,341 @@ uint16_t AP_Frsky_SPort_Passthrough::prep_number(int32_t number, uint8_t digits,
}
return res ;
}
/*
* Queue uplink packets in the sport rx queue
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : queue_rx_packet ( const AP_Frsky_SPort : : sport_packet_t packet )
{
// queue only Uplink packets
if ( packet . sensor = = _SPort_bidir . uplink_sensor_id & & packet . frame = = SPORT_UPLINK_FRAME ) {
_SPort_bidir . rx_packet_queue . push_force ( packet ) ;
}
}
/*
* Extract up to 1 mavlite message from the sport rx packet queue
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : process_rx_queue ( )
{
AP_Frsky_SPort : : sport_packet_t packet ;
uint8_t loop_count = 0 ; // prevent looping forever
while ( _SPort_bidir . rx_packet_queue . pop ( packet ) & & loop_count + + < MAVLITE_MSG_SPORT_PACKETS_COUNT ( MAVLITE_MAX_PAYLOAD_LEN ) ) {
AP_Frsky_MAVlite : : mavlite_message_t rxmsg ;
if ( _mavlite_handler . parse ( rxmsg , packet ) ) {
mavlite_process_message ( rxmsg ) ;
break ; // process only 1 mavlite message each call
}
}
}
/*
* Process the sport tx queue
* pop and send 1 sport packet
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : process_tx_queue ( )
{
AP_Frsky_SPort : : sport_packet_t packet ;
if ( ! _SPort_bidir . tx_packet_queue . peek ( packet ) ) {
return ;
}
// when using fport repeat each packet to account for
// fport packet loss (around 15%)
if ( ! _use_external_data | | _SPort_bidir . tx_packet_duplicates + + = = SPORT_TX_PACKET_DUPLICATES ) {
_SPort_bidir . tx_packet_queue . pop ( ) ;
_SPort_bidir . tx_packet_duplicates = 0 ;
}
send_sport_frame ( SPORT_DOWNLINK_FRAME , packet . appid , packet . data ) ;
}
/*
* Handle the COMMAND_LONG mavlite message
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : mavlite_handle_command_long ( const AP_Frsky_MAVlite : : mavlite_message_t & rxmsg )
{
mavlink_command_long_t mav_command_long { } ;
uint8_t cmd_options ;
float params [ 7 ] { } ;
AP_Frsky_MAVlite : : mavlite_msg_get_uint16 ( mav_command_long . command , rxmsg , 0 ) ;
AP_Frsky_MAVlite : : mavlite_msg_get_uint8 ( cmd_options , rxmsg , 2 ) ;
uint8_t param_count = AP_Frsky_MAVlite : : bit8_unpack ( cmd_options , 3 , 0 ) ; // first 3 bits
for ( uint8_t cmd_idx = 0 ; cmd_idx < param_count ; cmd_idx + + ) {
AP_Frsky_MAVlite : : mavlite_msg_get_float ( params [ cmd_idx ] , rxmsg , 3 + ( 4 * cmd_idx ) ) ; // base offset is 3, relative offset is 4*cmd_idx
}
mav_command_long . param1 = params [ 0 ] ;
mav_command_long . param2 = params [ 1 ] ;
mav_command_long . param3 = params [ 2 ] ;
mav_command_long . param4 = params [ 3 ] ;
mav_command_long . param5 = params [ 4 ] ;
mav_command_long . param6 = params [ 5 ] ;
mav_command_long . param7 = params [ 6 ] ;
MAV_RESULT mav_result = MAV_RESULT_FAILED ;
// filter allowed commands
switch ( mav_command_long . command ) {
//case MAV_CMD_ACCELCAL_VEHICLE_POS:
case MAV_CMD_DO_SET_MODE :
if ( AP : : vehicle ( ) - > set_mode ( mav_command_long . param1 , ModeReason : : FRSKY_COMMAND ) ) {
mav_result = MAV_RESULT_ACCEPTED ;
}
break ;
//case MAV_CMD_DO_SET_HOME:
case MAV_CMD_DO_FENCE_ENABLE :
mav_result = mavlite_handle_command_do_fence_enable ( ( uint16_t ) mav_command_long . param1 ) ;
break ;
case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN :
if ( is_equal ( mav_command_long . param1 , 1.0f ) & & is_zero ( mav_command_long . param2 ) ) {
mav_result = mavlite_handle_command_preflight_reboot ( ) ;
}
break ;
//case MAV_CMD_DO_START_MAG_CAL:
//case MAV_CMD_DO_ACCEPT_MAG_CAL:
//case MAV_CMD_DO_CANCEL_MAG_CAL:
//case MAV_CMD_START_RX_PAIR:
//case MAV_CMD_DO_DIGICAM_CONFIGURE:
//case MAV_CMD_DO_DIGICAM_CONTROL:
//case MAV_CMD_DO_SET_CAM_TRIGG_DIST:
//case MAV_CMD_DO_GRIPPER:
//case MAV_CMD_DO_MOUNT_CONFIGURE:
//case MAV_CMD_DO_MOUNT_CONTROL:
//case MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES:
//case MAV_CMD_DO_SET_ROI_SYSID:
//case MAV_CMD_DO_SET_ROI_LOCATION:
//case MAV_CMD_DO_SET_ROI:
case MAV_CMD_PREFLIGHT_CALIBRATION :
if ( is_equal ( mav_command_long . param1 , 0.0f ) & & is_equal ( mav_command_long . param2 , 0.0f ) & & is_equal ( mav_command_long . param3 , 1.0f ) ) {
mav_result = mavlite_handle_command_preflight_calibration_baro ( ) ;
}
break ;
//case MAV_CMD_BATTERY_RESET:
//case MAV_CMD_PREFLIGHT_UAVCAN:
//case MAV_CMD_FLASH_BOOTLOADER:
//case MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS:
//case MAV_CMD_GET_HOME_POSITION:
//case MAV_CMD_PREFLIGHT_STORAGE:
//case MAV_CMD_SET_MESSAGE_INTERVAL:
//case MAV_CMD_GET_MESSAGE_INTERVAL:
//case MAV_CMD_REQUEST_MESSAGE:
//case MAV_CMD_DO_SET_SERVO:
//case MAV_CMD_DO_REPEAT_SERVO:
//case MAV_CMD_DO_SET_RELAY:
//case MAV_CMD_DO_REPEAT_RELAY:
//case MAV_CMD_DO_FLIGHTTERMINATION:
//case MAV_CMD_COMPONENT_ARM_DISARM:
//case MAV_CMD_FIXED_MAG_CAL_YAW:
default :
mav_result = MAV_RESULT_UNSUPPORTED ;
break ;
}
mavlite_send_command_ack ( mav_result , mav_command_long . command ) ;
}
void AP_Frsky_SPort_Passthrough : : mavlite_send_command_ack ( const MAV_RESULT mav_result , const uint16_t cmdid )
{
AP_Frsky_MAVlite : : mavlite_message_t txmsg ;
txmsg . msgid = MAVLINK_MSG_ID_COMMAND_ACK ;
AP_Frsky_MAVlite : : mavlite_msg_set_uint16 ( txmsg , cmdid , 0 ) ;
AP_Frsky_MAVlite : : mavlite_msg_set_uint8 ( txmsg , ( uint8_t ) mav_result , 2 ) ;
mavlite_send_message ( txmsg ) ;
}
MAV_RESULT AP_Frsky_SPort_Passthrough : : mavlite_handle_command_preflight_calibration_baro ( )
{
if ( hal . util - > get_soft_armed ( ) ) {
return MAV_RESULT_DENIED ;
}
// fast barometer calibration
gcs ( ) . send_text ( MAV_SEVERITY_INFO , " Updating barometer calibration " ) ;
AP : : baro ( ) . update_calibration ( ) ;
gcs ( ) . send_text ( MAV_SEVERITY_INFO , " Barometer calibration complete " ) ;
AP_Airspeed * airspeed = AP_Airspeed : : get_singleton ( ) ;
if ( airspeed ! = nullptr ) {
airspeed - > calibrate ( false ) ;
}
return MAV_RESULT_ACCEPTED ;
}
MAV_RESULT AP_Frsky_SPort_Passthrough : : mavlite_handle_command_do_fence_enable ( uint16_t param1 )
{
AC_Fence * fence = AP : : fence ( ) ;
if ( fence = = nullptr ) {
return MAV_RESULT_UNSUPPORTED ;
}
switch ( param1 ) {
case 0 :
fence - > enable ( false ) ;
return MAV_RESULT_ACCEPTED ;
case 1 :
fence - > enable ( true ) ;
return MAV_RESULT_ACCEPTED ;
default :
return MAV_RESULT_FAILED ;
}
}
/*
* Handle the PARAM_REQUEST_READ mavlite message
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : mavlite_handle_param_request_read ( const AP_Frsky_MAVlite : : mavlite_message_t & rxmsg )
{
float param_value ;
char param_name [ AP_MAX_NAME_SIZE + 1 ] ;
AP_Frsky_MAVlite : : mavlite_msg_get_string ( param_name , rxmsg , 0 ) ;
// find existing param
if ( ! AP_Param : : get ( param_name , param_value ) ) {
gcs ( ) . send_text ( MAV_SEVERITY_WARNING , " Param read failed (%s) " , param_name ) ;
return ;
}
AP_Frsky_MAVlite : : mavlite_message_t txmsg ;
txmsg . msgid = MAVLINK_MSG_ID_PARAM_VALUE ;
AP_Frsky_MAVlite : : mavlite_msg_set_float ( txmsg , param_value , 0 ) ;
AP_Frsky_MAVlite : : mavlite_msg_set_string ( txmsg , param_name , 4 ) ;
mavlite_send_message ( txmsg ) ;
}
/*
* Handle the PARAM_SET mavlite message
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : mavlite_handle_param_set ( const AP_Frsky_MAVlite : : mavlite_message_t & rxmsg )
{
float param_value ;
char param_name [ AP_MAX_NAME_SIZE + 1 ] ;
// populate packet with mavlite payload
AP_Frsky_MAVlite : : mavlite_msg_get_float ( param_value , rxmsg , 0 ) ;
AP_Frsky_MAVlite : : mavlite_msg_get_string ( param_name , rxmsg , 4 ) ;
// find existing param so we can get the old value
enum ap_var_type var_type ;
// set parameter
AP_Param * vp ;
uint16_t parameter_flags = 0 ;
vp = AP_Param : : find ( param_name , & var_type , & parameter_flags ) ;
if ( vp = = nullptr | | isnan ( param_value ) | | isinf ( param_value ) ) {
return ;
}
if ( ( parameter_flags & AP_PARAM_FLAG_INTERNAL_USE_ONLY ) | | vp - > is_read_only ( ) ) {
gcs ( ) . send_text ( MAV_SEVERITY_WARNING , " Param write denied (%s) " , param_name ) ;
} else if ( ! AP_Param : : set_and_save ( param_name , param_value ) ) {
gcs ( ) . send_text ( MAV_SEVERITY_WARNING , " Param write failed (%s) " , param_name ) ;
}
// let's read back the last value, either the readonly one or the updated one
if ( ! AP_Param : : get ( param_name , param_value ) ) {
gcs ( ) . send_text ( MAV_SEVERITY_WARNING , " Param read failed (%s) " , param_name ) ;
return ;
}
AP_Frsky_MAVlite : : mavlite_message_t txmsg ;
txmsg . msgid = MAVLINK_MSG_ID_PARAM_VALUE ;
AP_Frsky_MAVlite : : mavlite_msg_set_float ( txmsg , param_value , 0 ) ;
AP_Frsky_MAVlite : : mavlite_msg_set_string ( txmsg , param_name , 4 ) ;
mavlite_send_message ( txmsg ) ;
}
/*
Handle a MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN command
for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
Optionally disable PX4IO overrides . This is done for quadplanes to
prevent the mixer running while rebooting which can start the VTOL
motors . That can be dangerous when a preflight reboot is done with
the pilot close to the aircraft and can also damage the aircraft
*/
MAV_RESULT AP_Frsky_SPort_Passthrough : : mavlite_handle_command_preflight_reboot ( void )
{
if ( hal . util - > get_soft_armed ( ) ) {
// refuse reboot when armed
return MAV_RESULT_FAILED ;
}
# if APM_BUILD_TYPE(APM_BUILD_ArduSub)
SRV_Channels : : zero_rc_outputs ( ) ;
# endif
// send ack before we reboot
mavlite_send_command_ack ( MAV_RESULT_ACCEPTED , MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN ) ;
// Notify might want to blink some LEDs:
AP_Notify * notify = AP_Notify : : get_singleton ( ) ;
if ( notify ) {
AP_Notify : : flags . firmware_update = 1 ;
notify - > update ( ) ;
}
// force safety on
hal . rcout - > force_safety_on ( ) ;
// flush pending parameter writes
AP_Param : : flush ( ) ;
// do not process incoming mavlink messages while we delay:
hal . scheduler - > register_delay_callback ( nullptr , 5 ) ;
// delay to give the ACK a chance to get out, the LEDs to flash,
// the IO board safety to be forced on, the parameters to flush, ...
hal . scheduler - > delay ( 1000 ) ;
hal . scheduler - > reboot ( false ) ;
return MAV_RESULT_FAILED ;
}
/*
* Process an incoming mavlite message
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : mavlite_process_message ( const AP_Frsky_MAVlite : : mavlite_message_t & rxmsg )
{
switch ( rxmsg . msgid ) {
case MAVLINK_MSG_ID_PARAM_REQUEST_READ :
mavlite_handle_param_request_read ( rxmsg ) ;
break ;
case MAVLINK_MSG_ID_PARAM_SET :
mavlite_handle_param_set ( rxmsg ) ;
break ;
case MAVLINK_MSG_ID_COMMAND_LONG :
mavlite_handle_command_long ( rxmsg ) ;
break ;
}
}
/*
* Send a mavlite message
* Message is chunked in sport packets pushed in the tx queue
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
bool AP_Frsky_SPort_Passthrough : : mavlite_send_message ( AP_Frsky_MAVlite : : mavlite_message_t & txmsg )
{
return _mavlite_handler . encode ( _SPort_bidir . tx_packet_queue , txmsg ) ;
}
/*
* Utility method to apply constraints in changing sensor id values
* for FrSky SPort Passthrough ( OpenTX ) protocol ( X - receivers )
*/
void AP_Frsky_SPort_Passthrough : : set_sensor_id ( AP_Int8 param_idx , uint8_t & sensor )
{
int8_t idx = param_idx . get ( ) ;
if ( idx = = - 1 ) {
// disable this sensor
sensor = 0xFF ;
return ;
}
sensor = calc_sensor_id ( idx ) ;
}
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL