Update cloud build defines (#14080)
[betaflight.git] / src / main / telemetry / ibus.c
blobe302d0a8312213c53e2635550e03598adbefcb18
1 /*
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)
8 * any later version.
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.
30 #include <stdbool.h>
31 #include <stdint.h>
32 #include <string.h>
34 #include "platform.h"
36 #if defined(USE_TELEMETRY_IBUS)
38 #include "common/axis.h"
40 #include "common/utils.h"
42 #include "pg/pg.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) {
104 return;
107 while (serialRxBytesWaiting(ibusSerialPort) > 0) {
108 uint8_t c = serialRead(ibusSerialPort);
110 if (outboundBytesToIgnoreOnRxCount) {
111 outboundBytesToIgnoreOnRxCount--;
112 continue;
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) {
128 return false;
131 if (newTelemetryEnabledValue) {
132 rescheduleTask(TASK_TELEMETRY, IBUS_TASK_PERIOD_US);
133 configureIbusTelemetryPort();
134 } else {
135 freeIbusTelemetryPort();
138 return true;
141 void configureIbusTelemetryPort(void)
143 if (!ibusSerialPortConfig) {
144 return;
147 if (isSerialPortShared(ibusSerialPortConfig, FUNCTION_RX_SERIAL, FUNCTION_TELEMETRY_IBUS)) {
148 // serialRx will open port and handle telemetry
149 return;
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) {
155 return;
158 initSharedIbusTelemetry(ibusSerialPort);
159 ibusTelemetryEnabled = true;
160 outboundBytesToIgnoreOnRxCount = 0;
163 void freeIbusTelemetryPort(void)
165 closeSerialPort(ibusSerialPort);
166 ibusSerialPort = NULL;
167 ibusTelemetryEnabled = false;
170 #endif