You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.3 KiB
149 lines
4.3 KiB
/* |
|
|
|
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 |
|
|
|
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 |
|
*/ |
|
|
|
#include "AP_Frsky_Telem.h" |
|
#include "AP_Frsky_Parameters.h" |
|
|
|
#include <AP_SerialManager/AP_SerialManager.h> |
|
|
|
#include <AP_Vehicle/AP_Vehicle.h> |
|
|
|
#include "AP_Frsky_D.h" |
|
#include "AP_Frsky_SPort.h" |
|
#include "AP_Frsky_SPort_Passthrough.h" |
|
|
|
extern const AP_HAL::HAL& hal; |
|
|
|
AP_Frsky_Telem *AP_Frsky_Telem::singleton; |
|
|
|
AP_Frsky_Telem::AP_Frsky_Telem() |
|
{ |
|
singleton = this; |
|
#if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL |
|
_frsky_parameters = &AP::vehicle()->frsky_parameters; |
|
#endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL |
|
} |
|
|
|
|
|
AP_Frsky_Telem::~AP_Frsky_Telem(void) |
|
{ |
|
singleton = nullptr; |
|
} |
|
|
|
/* |
|
* init - perform required initialisation |
|
*/ |
|
bool AP_Frsky_Telem::init(bool use_external_data) |
|
{ |
|
const AP_SerialManager &serial_manager = AP::serialmanager(); |
|
|
|
// 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) |
|
AP_HAL::UARTDriver *port; |
|
if ((port = serial_manager.find_serial(AP_SerialManager::SerialProtocol_FrSky_D, 0))) { |
|
_backend = new AP_Frsky_D(port); |
|
} else if ((port = serial_manager.find_serial(AP_SerialManager::SerialProtocol_FrSky_SPort, 0))) { |
|
_backend = new AP_Frsky_SPort(port); |
|
} else if (use_external_data || (port = serial_manager.find_serial(AP_SerialManager::SerialProtocol_FrSky_SPort_Passthrough, 0))) { |
|
_backend = new AP_Frsky_SPort_Passthrough(port, use_external_data, _frsky_parameters); |
|
} |
|
|
|
if (_backend == nullptr) { |
|
return false; |
|
} |
|
|
|
if (!_backend->init()) { |
|
delete _backend; |
|
_backend = nullptr; |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
bool AP_Frsky_Telem::_get_telem_data(AP_Frsky_Backend::sport_packet_t* packet_array, uint8_t &packet_count, const uint8_t max_size) |
|
{ |
|
if (_backend == nullptr) { |
|
return false; |
|
} |
|
if (packet_array == nullptr) { |
|
return false; |
|
} |
|
return _backend->get_telem_data(packet_array, packet_count, max_size); |
|
} |
|
|
|
#if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL |
|
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); |
|
} |
|
#endif |
|
|
|
void AP_Frsky_Telem::try_create_singleton_for_external_data() |
|
{ |
|
// try to allocate an AP_Frsky_Telem object only if we are disarmed |
|
if (!singleton && !hal.util->get_soft_armed()) { |
|
new AP_Frsky_Telem(); |
|
// initialize the passthrough scheduler |
|
if (singleton) { |
|
singleton->init(true); |
|
} |
|
} |
|
} |
|
|
|
/* |
|
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(); |
|
if (singleton == nullptr) { |
|
return false; |
|
} |
|
return singleton->_get_telem_data(packet_array, packet_count, max_size); |
|
} |
|
|
|
#if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL |
|
/* |
|
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) |
|
{ |
|
try_create_singleton_for_external_data(); |
|
if (singleton == nullptr) { |
|
return false; |
|
} |
|
return singleton->_set_telem_data(frame, appid, data); |
|
} |
|
#endif |
|
|
|
namespace AP |
|
{ |
|
AP_Frsky_Telem *frsky_telem() |
|
{ |
|
return AP_Frsky_Telem::get_singleton(); |
|
} |
|
};
|
|
|