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"
65 #define IBUS_TASK_PERIOD_US (1000)
67 #define IBUS_UART_MODE (MODE_RXTX)
68 #define IBUS_BAUDRATE (115200)
69 #define IBUS_CYCLE_TIME_MS (8)
71 #define IBUS_MIN_LEN (2 + IBUS_CHECKSUM_SIZE)
72 #define IBUS_MAX_TX_LEN (6)
73 #define IBUS_MAX_RX_LEN (4)
74 #define IBUS_RX_BUF_LEN (IBUS_MAX_RX_LEN)
76 static serialPort_t
*ibusSerialPort
= NULL
;
77 static const serialPortConfig_t
*ibusSerialPortConfig
;
79 /* The sent bytes will be echoed back since Tx and Rx are wired together, this counter
80 * will keep track of how many rx chars that shall be discarded */
81 static uint8_t outboundBytesToIgnoreOnRxCount
= 0;
83 static bool ibusTelemetryEnabled
= false;
84 static portSharing_e ibusPortSharing
;
86 static uint8_t ibusReceiveBuffer
[IBUS_RX_BUF_LEN
] = { 0x0 };
88 static void pushOntoTail(uint8_t buffer
[IBUS_MIN_LEN
], size_t bufferLength
, uint8_t value
)
90 memmove(buffer
, buffer
+ 1, bufferLength
- 1);
91 ibusReceiveBuffer
[bufferLength
- 1] = value
;
94 void initIbusTelemetry(void)
96 ibusSerialPortConfig
= findSerialPortConfig(FUNCTION_TELEMETRY_IBUS
);
97 ibusPortSharing
= determinePortSharing(ibusSerialPortConfig
, FUNCTION_TELEMETRY_IBUS
);
98 ibusTelemetryEnabled
= false;
101 void handleIbusTelemetry(void)
103 if (!ibusTelemetryEnabled
) {
107 while (serialRxBytesWaiting(ibusSerialPort
) > 0) {
108 uint8_t c
= serialRead(ibusSerialPort
);
110 if (outboundBytesToIgnoreOnRxCount
) {
111 outboundBytesToIgnoreOnRxCount
--;
115 pushOntoTail(ibusReceiveBuffer
, IBUS_RX_BUF_LEN
, c
);
117 if (isChecksumOkIa6b(ibusReceiveBuffer
, IBUS_RX_BUF_LEN
)) {
118 outboundBytesToIgnoreOnRxCount
+= respondToIbusRequest(ibusReceiveBuffer
);
123 bool checkIbusTelemetryState(void)
125 bool newTelemetryEnabledValue
= telemetryDetermineEnabledState(ibusPortSharing
);
127 if (newTelemetryEnabledValue
== ibusTelemetryEnabled
) {
131 if (newTelemetryEnabledValue
) {
132 rescheduleTask(TASK_TELEMETRY
, IBUS_TASK_PERIOD_US
);
133 configureIbusTelemetryPort();
135 freeIbusTelemetryPort();
141 void configureIbusTelemetryPort(void)
143 if (!ibusSerialPortConfig
) {
147 if (isSerialPortShared(ibusSerialPortConfig
, FUNCTION_RX_SERIAL
, FUNCTION_TELEMETRY_IBUS
)) {
148 // serialRx will open port and handle telemetry
152 ibusSerialPort
= openSerialPort(ibusSerialPortConfig
->identifier
, FUNCTION_TELEMETRY_IBUS
, NULL
, NULL
, IBUS_BAUDRATE
, IBUS_UART_MODE
, SERIAL_BIDIR
| (telemetryConfig()->telemetry_inverted
? SERIAL_INVERTED
: SERIAL_NOT_INVERTED
));
154 if (!ibusSerialPort
) {
158 initSharedIbusTelemetry(ibusSerialPort
);
159 ibusTelemetryEnabled
= true;
160 outboundBytesToIgnoreOnRxCount
= 0;
163 void freeIbusTelemetryPort(void)
165 closeSerialPort(ibusSerialPort
);
166 ibusSerialPort
= NULL
;
167 ibusTelemetryEnabled
= false;