2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 * FlySky iBus telemetry implementation by CraigJPerry.
23 * Unit tests and some additions by Unitware
25 * Many thanks to Dave Borthwick's iBus telemetry dongle converter for
26 * PIC 12F1572 (also distributed under GPLv3) which was referenced to
27 * clarify the protocol.
36 #if defined(USE_TELEMETRY_IBUS)
38 #include "common/axis.h"
40 #include "common/utils.h"
43 #include "pg/pg_ids.h"
45 #include "drivers/accgyro/accgyro.h"
46 #include "drivers/sensor.h"
47 #include "drivers/serial.h"
49 #include "fc/rc_controls.h"
51 #include "io/serial.h"
53 #include "sensors/acceleration.h"
54 #include "sensors/battery.h"
55 #include "sensors/barometer.h"
56 #include "sensors/gyro.h"
57 #include "sensors/sensors.h"
59 #include "scheduler/scheduler.h"
61 #include "telemetry/ibus.h"
62 #include "telemetry/ibus_shared.h"
63 #include "telemetry/telemetry.h"
66 #define IBUS_TASK_PERIOD_US (1000)
68 #define IBUS_UART_MODE (MODE_RXTX)
69 #define IBUS_BAUDRATE (115200)
70 #define IBUS_CYCLE_TIME_MS (8)
72 #define IBUS_MIN_LEN (2 + IBUS_CHECKSUM_SIZE)
73 #define IBUS_MAX_TX_LEN (6)
74 #define IBUS_MAX_RX_LEN (4)
75 #define IBUS_RX_BUF_LEN (IBUS_MAX_RX_LEN)
78 static serialPort_t
*ibusSerialPort
= NULL
;
79 static const serialPortConfig_t
*ibusSerialPortConfig
;
81 /* The sent bytes will be echoed back since Tx and Rx are wired together, this counter
82 * will keep track of how many rx chars that shall be discarded */
83 static uint8_t outboundBytesToIgnoreOnRxCount
= 0;
85 static bool ibusTelemetryEnabled
= false;
86 static portSharing_e ibusPortSharing
;
88 static uint8_t ibusReceiveBuffer
[IBUS_RX_BUF_LEN
] = { 0x0 };
92 static void pushOntoTail(uint8_t buffer
[IBUS_MIN_LEN
], size_t bufferLength
, uint8_t value
)
94 memmove(buffer
, buffer
+ 1, bufferLength
- 1);
95 ibusReceiveBuffer
[bufferLength
- 1] = value
;
99 void initIbusTelemetry(void)
101 ibusSerialPortConfig
= findSerialPortConfig(FUNCTION_TELEMETRY_IBUS
);
102 ibusPortSharing
= determinePortSharing(ibusSerialPortConfig
, FUNCTION_TELEMETRY_IBUS
);
103 ibusTelemetryEnabled
= false;
107 void handleIbusTelemetry(void)
109 if (!ibusTelemetryEnabled
) {
113 while (serialRxBytesWaiting(ibusSerialPort
) > 0) {
114 uint8_t c
= serialRead(ibusSerialPort
);
116 if (outboundBytesToIgnoreOnRxCount
) {
117 outboundBytesToIgnoreOnRxCount
--;
121 pushOntoTail(ibusReceiveBuffer
, IBUS_RX_BUF_LEN
, c
);
123 if (isChecksumOkIa6b(ibusReceiveBuffer
, IBUS_RX_BUF_LEN
)) {
124 outboundBytesToIgnoreOnRxCount
+= respondToIbusRequest(ibusReceiveBuffer
);
130 bool checkIbusTelemetryState(void)
132 bool newTelemetryEnabledValue
= telemetryDetermineEnabledState(ibusPortSharing
);
134 if (newTelemetryEnabledValue
== ibusTelemetryEnabled
) {
138 if (newTelemetryEnabledValue
) {
139 rescheduleTask(TASK_TELEMETRY
, IBUS_TASK_PERIOD_US
);
140 configureIbusTelemetryPort();
142 freeIbusTelemetryPort();
149 void configureIbusTelemetryPort(void)
151 if (!ibusSerialPortConfig
) {
155 if (isSerialPortShared(ibusSerialPortConfig
, FUNCTION_RX_SERIAL
, FUNCTION_TELEMETRY_IBUS
)) {
156 // serialRx will open port and handle telemetry
160 ibusSerialPort
= openSerialPort(ibusSerialPortConfig
->identifier
, FUNCTION_TELEMETRY_IBUS
, NULL
, NULL
, IBUS_BAUDRATE
, IBUS_UART_MODE
, SERIAL_BIDIR
| (telemetryConfig()->telemetry_inverted
? SERIAL_INVERTED
: SERIAL_NOT_INVERTED
));
162 if (!ibusSerialPort
) {
166 initSharedIbusTelemetry(ibusSerialPort
);
167 ibusTelemetryEnabled
= true;
168 outboundBytesToIgnoreOnRxCount
= 0;
172 void freeIbusTelemetryPort(void)
174 closeSerialPort(ibusSerialPort
);
175 ibusSerialPort
= NULL
;
176 ibusTelemetryEnabled
= false;