2014-07-28 19:21:07 -03:00
/*
2019-07-12 07:06:12 -03:00
Inspired by work done here
https : //github.com/PX4/Firmware/tree/master/src/drivers/frsky_telemetry from Stefan Rado <px4@sradonia.net>
https : //github.com/opentx/opentx/tree/2.3/radio/src/telemetry from the OpenTX team
2014-07-28 19:21:07 -03:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/*
FRSKY Telemetry library
*/
2018-09-21 03:22:04 -03:00
2022-04-16 23:54:07 -03:00
# include "AP_Frsky_config.h"
# if AP_FRSKY_TELEM_ENABLED
2015-08-11 03:28:43 -03:00
# include "AP_Frsky_Telem.h"
2020-09-10 09:55:53 -03:00
# include "AP_Frsky_Parameters.h"
2018-09-21 03:22:04 -03:00
2020-09-28 07:34:33 -03:00
# include <AP_SerialManager/AP_SerialManager.h>
2018-06-13 08:11:52 -03:00
2020-09-10 09:55:53 -03:00
# include <AP_Vehicle/AP_Vehicle.h>
2020-09-28 01:31:38 -03:00
# include "AP_Frsky_D.h"
# include "AP_Frsky_SPort.h"
# include "AP_Frsky_SPort_Passthrough.h"
2014-07-28 19:21:07 -03:00
extern const AP_HAL : : HAL & hal ;
2019-12-02 23:08:12 -04:00
AP_Frsky_Telem * AP_Frsky_Telem : : singleton ;
2020-09-28 01:31:38 -03:00
AP_Frsky_Telem : : AP_Frsky_Telem ( )
2019-06-18 04:39:56 -03:00
{
2019-12-02 23:08:12 -04:00
singleton = this ;
2020-09-10 09:55:53 -03:00
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
_frsky_parameters = & AP : : vehicle ( ) - > frsky_parameters ;
# endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
2019-12-02 23:08:12 -04:00
}
2020-09-10 09:55:53 -03:00
2019-12-02 23:08:12 -04:00
AP_Frsky_Telem : : ~ AP_Frsky_Telem ( void )
{
singleton = nullptr ;
}
2016-05-03 14:43:16 -03:00
/*
* init - perform required initialisation
2016-05-03 19:04:46 -03:00
*/
2020-09-28 01:31:38 -03:00
bool AP_Frsky_Telem : : init ( bool use_external_data )
2016-05-03 19:04:46 -03:00
{
2019-02-12 02:34:06 -04:00
const AP_SerialManager & serial_manager = AP : : serialmanager ( ) ;
2016-05-03 19:04:46 -03:00
// check for protocol configured for a serial port - only the first serial port with one of these protocols will then run (cannot have FrSky on multiple serial ports)
2020-09-28 01:31:38 -03:00
AP_HAL : : UARTDriver * port ;
if ( ( port = serial_manager . find_serial ( AP_SerialManager : : SerialProtocol_FrSky_D , 0 ) ) ) {
2022-04-16 23:54:07 -03:00
# if AP_FRSKY_D_TELEM_ENABLED
2024-05-26 22:24:11 -03:00
_backend = NEW_NOTHROW AP_Frsky_D ( port ) ;
2022-04-16 23:54:07 -03:00
# endif
2020-09-28 01:31:38 -03:00
} else if ( ( port = serial_manager . find_serial ( AP_SerialManager : : SerialProtocol_FrSky_SPort , 0 ) ) ) {
2022-04-16 23:54:07 -03:00
# if AP_FRSKY_SPORT_TELEM_ENABLED
2024-05-26 22:24:11 -03:00
_backend = NEW_NOTHROW AP_Frsky_SPort ( port ) ;
2022-04-16 23:54:07 -03:00
# endif
2020-09-28 01:31:38 -03:00
} else if ( use_external_data | | ( port = serial_manager . find_serial ( AP_SerialManager : : SerialProtocol_FrSky_SPort_Passthrough , 0 ) ) ) {
2022-04-16 23:54:07 -03:00
# if AP_FRSKY_SPORT_PASSTHROUGH_ENABLED
2024-05-26 22:24:11 -03:00
_backend = NEW_NOTHROW AP_Frsky_SPort_Passthrough ( port , use_external_data , _frsky_parameters ) ;
2022-04-16 23:54:07 -03:00
# endif
2020-09-28 01:31:38 -03:00
}
if ( _backend = = nullptr ) {
return false ;
}
if ( ! _backend - > init ( ) ) {
delete _backend ;
_backend = nullptr ;
return false ;
2016-05-03 19:04:46 -03:00
}
2019-06-18 04:32:31 -03:00
2020-09-28 01:31:38 -03:00
return true ;
2016-05-03 19:04:46 -03:00
}
2020-12-10 05:28:56 -04:00
bool AP_Frsky_Telem : : _get_telem_data ( AP_Frsky_Backend : : sport_packet_t * packet_array , uint8_t & packet_count , const uint8_t max_size )
2020-09-28 01:31:38 -03:00
{
if ( _backend = = nullptr ) {
return false ;
}
2020-12-10 05:28:56 -04:00
if ( packet_array = = nullptr ) {
return false ;
}
return _backend - > get_telem_data ( packet_array , packet_count , max_size ) ;
2020-09-28 01:31:38 -03:00
}
2020-11-18 13:16:15 -04:00
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
2020-09-10 09:55:53 -03:00
bool AP_Frsky_Telem : : _set_telem_data ( uint8_t frame , uint16_t appid , uint32_t data )
{
if ( _backend = = nullptr ) {
return false ;
}
return _backend - > set_telem_data ( frame , appid , data ) ;
}
2020-11-18 13:16:15 -04:00
# endif
2020-09-10 09:55:53 -03:00
2020-12-10 05:28:56 -04:00
void AP_Frsky_Telem : : try_create_singleton_for_external_data ( )
2020-01-01 02:32:04 -04:00
{
2020-12-10 05:28:56 -04:00
// try to allocate an AP_Frsky_Telem object only if we are disarmed
2020-01-01 02:32:04 -04:00
if ( ! singleton & & ! hal . util - > get_soft_armed ( ) ) {
2024-05-26 22:24:11 -03:00
NEW_NOTHROW AP_Frsky_Telem ( ) ;
2020-01-10 03:06:15 -04:00
// initialize the passthrough scheduler
if ( singleton ) {
2020-09-28 01:31:38 -03:00
singleton - > init ( true ) ;
2020-01-10 03:06:15 -04:00
}
2020-01-01 02:32:04 -04:00
}
2020-12-10 05:28:56 -04:00
}
/*
fetch Sport data for an external transport , such as FPort
*/
bool AP_Frsky_Telem : : get_telem_data ( AP_Frsky_Backend : : sport_packet_t * packet_array , uint8_t & packet_count , const uint8_t max_size )
{
try_create_singleton_for_external_data ( ) ;
2020-09-10 09:55:53 -03:00
if ( singleton = = nullptr ) {
2020-01-01 02:32:04 -04:00
return false ;
}
2020-12-10 05:28:56 -04:00
return singleton - > _get_telem_data ( packet_array , packet_count , max_size ) ;
2020-01-01 02:32:04 -04:00
}
2020-11-18 13:16:15 -04:00
# if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
2020-09-10 09:55:53 -03:00
/*
allow external transports ( e . g . FPort ) , to supply telemetry data
*/
bool AP_Frsky_Telem : : set_telem_data ( const uint8_t frame , const uint16_t appid , const uint32_t data )
{
2020-12-10 05:28:56 -04:00
try_create_singleton_for_external_data ( ) ;
2020-09-10 09:55:53 -03:00
if ( singleton = = nullptr ) {
return false ;
2019-12-02 23:08:12 -04:00
}
2020-09-10 09:55:53 -03:00
return singleton - > _set_telem_data ( frame , appid , data ) ;
}
2020-11-18 13:16:15 -04:00
# endif
2020-09-10 09:55:53 -03:00
namespace AP
{
AP_Frsky_Telem * frsky_telem ( )
{
return AP_Frsky_Telem : : get_singleton ( ) ;
}
2019-12-02 23:08:12 -04:00
} ;
2022-04-16 23:54:07 -03:00
# endif // AP_FRSKY_TELEM_ENABLED