diff --git a/Makefile b/Makefile
index d4849c981..4e5f71503 100644
--- a/Makefile
+++ b/Makefile
@@ -315,6 +315,7 @@ COMMON_SRC = build_config.c \
rx/spektrum.c \
rx/xbus.c \
rx/ibus.c \
+ rx/jetiexbus.c \
sensors/acceleration.c \
sensors/battery.c \
sensors/boardalignment.c \
diff --git a/src/main/io/serial_cli.c b/src/main/io/serial_cli.c
index cf901b93b..2b2893361 100644
--- a/src/main/io/serial_cli.c
+++ b/src/main/io/serial_cli.c
@@ -361,7 +361,8 @@ static const char * const lookupTableSerialRX[] = {
"SUMH",
"XB-B",
"XB-B-RJ01",
- "IBUS"
+ "IBUS",
+ "JETIEXBUS"
};
static const char * const lookupTableGyroLpf[] = {
diff --git a/src/main/rx/jetiexbus.c b/src/main/rx/jetiexbus.c
new file mode 100644
index 000000000..cdb650610
--- /dev/null
+++ b/src/main/rx/jetiexbus.c
@@ -0,0 +1,591 @@
+/*
+ * This file is part of Cleanflight.
+ *
+ * Cleanflight 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.
+ *
+ * Cleanflight 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 Cleanflight. If not, see .
+ *
+ * Authors:
+ * Thomas Miric - marv-t
+ *
+ * Jeti EX Bus Communication Protocol:
+ * http://www.jetimodel.com/en/show-file/642/
+ *
+ * JETI Telemetry Communication Protocol:
+ * http://www.jetimodel.com/en/show-file/26/
+ *
+ * Following restrictions:
+ * Communication speed: 125000 bps
+ * Number of channels: 16
+ *
+ * Connect as follows:
+ * Jeti EX Bus -> Serial RX (connect directly)
+ * Serial TX -> Resistor(2k4) ->Serial RX
+ * In jeti pdf it is different, but if the resistor breaks, the receiver continues to operate.
+ *
+ */
+
+#include
+#include
+
+#include "platform.h"
+#include "build_config.h"
+#include "drivers/system.h"
+#include "drivers/serial.h"
+#include "drivers/serial_uart.h"
+#include "io/serial.h"
+#include "rx/jetiexbus.h"
+
+
+#ifdef TELEMETRY
+
+#include
+#include "sensors/sensors.h"
+#include "sensors/battery.h"
+#include "sensors/barometer.h"
+#include "telemetry/telemetry.h"
+
+#endif //TELEMETRY
+
+#include "rx/rx.h"
+
+//
+// Serial driver for Jeti EX Bus receiver
+//
+#define JETIEXBUS_BAUDRATE 125000 // EX Bus 125000; EX Bus HS 250000 not supported
+#define JETIEXBUS_OPTIONS (SERIAL_STOPBITS_1 | SERIAL_PARITY_NO | SERIAL_NOT_INVERTED )
+
+#define JETIEXBUS_MIN_FRAME_GAP 1
+
+#define JETIEXBUS_CHANNEL_COUNT 16 // most Jeti TX transmit 16 channels
+#define JETIEXBUS_MIN_FRAME_SIZE 8
+#define JETIEXBUS_HEADER_LEN 6
+#define JETIEXBUS_CRC_LEN 2
+
+#define JETIEXBUS_MAX_FRAME_SIZE (JETIEXBUS_HEADER_LEN + JETIEXBUS_CHANNEL_COUNT*2 + JETIEXBUS_CRC_LEN)
+#define JETIEXBUS_FRAME_OFFSET (JETIEXBUS_MAX_FRAME_SIZE)
+#define JETIEXBUS_MAX_REQUESTFRAME_SIZE 8
+
+#define JETIEXBUS_START_CHANNEL_FRAME (0x3E)
+#define JETIEXBUS_START_REQUEST_FRAME (0x3D)
+
+#define EXBUS_CHANNELDATA (0x3E03) // Frame contains channeldata
+#define EXBUS_CHANNELDATA_TELEMETRY_REQUEST (0x3E01) // Frame contains channeldata, but with a request for data
+
+
+enum {
+ EXBUS_STATE_ZERO = 0,
+ EXBUS_STATE_IN_PROGRESS,
+ EXBUS_STATE_RECEIVED,
+ EXBUS_STATE_PROCESSED
+};
+
+enum {
+ EXBUS_TRANS_ZERO = 0,
+ EXBUS_TRANS_RX_READY,
+ EXBUS_TRANS_RX,
+ EXBUS_TRANS_TX_READY,
+ EXBUS_TRANS_TX
+};
+
+enum exBusHeader_e {
+ EXBUS_HEADER_SYNC = 0,
+ EXBUS_HEADER_REQ,
+ EXBUS_HEADER_MSG_LEN,
+ EXBUS_HEADER_PACKET_ID,
+ EXBUS_HEADER_DATA_ID,
+ EXBUS_HEADER_SUBLEN,
+ EXBUS_HEADER_DATA
+};
+
+#ifdef TELEMETRY
+
+enum exTelHeader_e {
+ EXTEL_HEADER_SYNC = 0,
+ EXTEL_HEADER_TYPE_LEN,
+ EXTEL_HEADER_USN_LB,
+ EXTEL_HEADER_USN_HB,
+ EXTEL_HEADER_LSN_LB,
+ EXTEL_HEADER_LSN_HB,
+ EXTEL_HEADER_RES,
+ EXTEL_HEADER_ID,
+ EXTEL_HEADER_DATA
+};
+
+
+enum exDataType_e {
+ EX_TYPE_6b = 0, // int6_t Data type 6b (-31 ¸31)
+ EX_TYPE_14b = 1, // int14_t Data type 14b (-8191 ¸8191)
+ EX_TYPE_22b = 4, // int22_t Data type 22b (-2097151 ¸2097151)
+ EX_TYPE_DT = 5, // int22_t Special data type – time and date
+ EX_TYPE_30b = 8, // int30_t Data type 30b (-536870911 ¸536870911)
+ EX_TYPE_GPS = 9 // int30_t Special data type – GPS coordinates: lo/hi minute - lo/hi degree.
+};
+
+typedef struct exBusSensor_s{
+ const char *name;
+ const char *unit;
+ int32_t value;
+ const uint8_t exDataType;
+ const uint32_t decimals;
+} exBusSensor_t;
+
+
+#define SETMASK(decimals, bytes) (decimals<<((bytes*8)-3))
+#define RESETMASK(bytes) (~(3 << ((bytes*8)-3)))
+
+const uint32_t resetMask[]={ RESETMASK(1), RESETMASK(2), RESETMASK(3), RESETMASK(4) };
+
+// list of telemetry messages
+// after 15 sensors must be a new Header : "CF-Dev 1.12 S2"
+
+exBusSensor_t jetiExSensors[] = {
+ { "CF-Dev 1.12 S1", "", 0, 0, 0 },
+ { "Voltage", "V", 0, EX_TYPE_14b, SETMASK(1,2) },
+ { "Current", "A", 0, EX_TYPE_14b, SETMASK(2,2) },
+ { "Altitude", "m", 0, EX_TYPE_14b, SETMASK(1,2) },
+ { "Capacity", "mAh", 0, EX_TYPE_14b, SETMASK(0,2) }
+};
+
+// after 15 sensors a new enum value to be set: EX_NEW_SENSOR = 17
+enum exSensors_e {
+ EX_VOLTAGE = 1,
+ EX_CURRENT,
+ EX_ALTITUDE,
+ EX_CAPACITY
+};
+
+#define JETI_EX_SENSOR_COUNT (sizeof(jetiExSensors) / sizeof(exBusSensor_t))
+
+#endif //TELEMETRY
+
+static serialPort_t *jetiExBusPort;
+static serialPortConfig_t *portConfig;
+
+static uint8_t jetiExBusFrameState = EXBUS_STATE_ZERO;
+static uint8_t jetiExBusRequestState = EXBUS_STATE_ZERO;
+static uint8_t jetiExBusFramePosition;
+static uint8_t jetiExBusFrameLength;
+
+// Use max values for ram areas
+static uint8_t jetiExBusSerialFrame[JETIEXBUS_MAX_FRAME_SIZE+JETIEXBUS_MAX_REQUESTFRAME_SIZE];
+static uint8_t *jetiExBusFrame;
+
+
+static uint16_t jetiExBusChannelData[JETIEXBUS_CHANNEL_COUNT];
+static void jetiExBusDataReceive(uint16_t c);
+static uint16_t jetiExBusReadRawRC(rxRuntimeConfig_t *rxRuntimeConfig, uint8_t chan);
+
+
+#ifdef TELEMETRY
+
+static uint8_t jetiExBusTelemetryFrame[JETIEXBUS_MAX_FRAME_SIZE];
+static uint8_t jetiExBusTransceiveState = EXBUS_TRANS_RX;
+static uint8_t *jetiExTelemetry=&jetiExBusTelemetryFrame[EXBUS_HEADER_DATA];
+static void sendJetiExBusTelemetry(uint8_t packetID);
+
+uint8_t updateCRC8( uint8_t crc, uint8_t data );
+uint8_t calcCRC8(uint8_t *pt, uint8_t msgLen);
+
+#endif //TELEMETRY
+
+uint16_t updateCRC16( uint16_t crc, uint8_t data );
+uint16_t calcCRC16(uint8_t *pt, uint8_t msgLen);
+
+
+
+
+bool jetiExBusInit(rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig, rcReadRawDataPtr *callback)
+{
+ UNUSED(rxConfig);
+
+ if (callback) {
+ *callback = jetiExBusReadRawRC;
+ }
+
+ rxRuntimeConfig->channelCount = JETIEXBUS_CHANNEL_COUNT;
+ jetiExBusFramePosition = 0;
+ jetiExBusFrameLength = JETIEXBUS_MAX_FRAME_SIZE;
+
+ portConfig = findSerialPortConfig(FUNCTION_RX_SERIAL);
+
+ if (!portConfig) {
+ return false;
+ }
+
+ jetiExBusPort = openSerialPort(portConfig->identifier, FUNCTION_RX_SERIAL, jetiExBusDataReceive, JETIEXBUS_BAUDRATE, MODE_RXTX, JETIEXBUS_OPTIONS );
+ serialSetMode(jetiExBusPort, MODE_RX);
+ return jetiExBusPort != NULL;
+}
+
+
+// Jeti Ex Bus crc calculations for single byte
+uint16_t updateCRC16( uint16_t crc, uint8_t data )
+{
+ uint16_t ret_val;
+ data ^= (uint8_t)(crc) & (uint8_t)(0xFF);
+ data ^= data << 4;
+ ret_val = ((((uint16_t)data << 8) | ((crc & 0xFF00) >> 8))
+ ^ (uint8_t)(data >> 4)
+ ^ ((uint16_t)data << 3));
+ return ret_val;
+}
+
+// Jeti Ex Bus crc calculations for a frame
+uint16_t calcCRC16(uint8_t *pt, uint8_t msgLen)
+{
+ uint16_t crc16_data=0;
+ uint8_t mlen=0;
+ while(mlen>3;
+ }
+ break;
+ }
+}
+
+void jetiExBusFrameReset(void)
+{
+ jetiExBusFramePosition = 0;
+ jetiExBusFrameLength = JETIEXBUS_MAX_FRAME_SIZE;
+}
+
+
+/*
+ supported:
+ 0x3E 0x01 LEN Packet_ID 0x31 SUB_LEN Data_array CRC16 // Channeldata with telemetrie request (second byte 0x01)
+ 0x3E 0x03 LEN Packet_ID 0x31 SUB_LEN Data_array CRC16 // Channeldata forbids answering (second byte 0x03)
+ 0x3D 0x01 0x08 Packet_ID 0x3A 0x00 CRC16 // Telemetrierequest EX telemetry (fifth byte 0x3A)
+
+ other messages - not supported:
+ 0x3D 0x01 0x09 Packet_ID 0x3B 0x01 0xF0 CRC16 // Jetibox request (fifth byte 0x3B)
+ ...
+
+*/
+// Receive ISR callback
+static void jetiExBusDataReceive(uint16_t c)
+{
+ uint32_t now;
+ static uint32_t jetiExBusTimeLast = 0;
+ static uint32_t jetiExBusTimeInterval;
+ static uint16_t crc = 0;
+
+ // Check if we shall reset frame position due to time
+ now = millis();
+
+ jetiExBusTimeInterval = now - jetiExBusTimeLast;
+ jetiExBusTimeLast = now;
+
+ if (jetiExBusTimeInterval > JETIEXBUS_MIN_FRAME_GAP) {
+ jetiExBusFrameReset();
+ jetiExBusFrameState = EXBUS_STATE_ZERO;
+ jetiExBusRequestState = EXBUS_STATE_ZERO;
+ }
+
+ // Check if we shall start a frame?
+ if (jetiExBusFramePosition == 0) {
+ switch(c){
+ case JETIEXBUS_START_CHANNEL_FRAME:
+ jetiExBusFrameState = EXBUS_STATE_IN_PROGRESS;
+ jetiExBusFrame = &jetiExBusSerialFrame[0];
+ break;
+
+ case JETIEXBUS_START_REQUEST_FRAME:
+ jetiExBusRequestState = EXBUS_STATE_IN_PROGRESS;
+ jetiExBusFrame = &jetiExBusSerialFrame[JETIEXBUS_MAX_FRAME_SIZE];
+ break;
+
+ default:
+ return;
+ }
+ crc = 0;
+ }
+
+ // Store in frame copy
+ jetiExBusFrame[jetiExBusFramePosition] = (uint8_t)c;
+ crc = updateCRC16(crc, (uint8_t)c);
+ jetiExBusFramePosition++;
+
+ // Check the header for the messagelength
+ if (jetiExBusFramePosition==JETIEXBUS_HEADER_LEN) {
+ if ((jetiExBusFrame[EXBUS_HEADER_MSG_LEN]<=JETIEXBUS_MAX_FRAME_SIZE) && (jetiExBusFrame[EXBUS_HEADER_MSG_LEN]>=JETIEXBUS_MIN_FRAME_SIZE)) {
+ jetiExBusFrameLength = jetiExBusFrame[EXBUS_HEADER_MSG_LEN];
+ } else {
+ jetiExBusFrameReset(); // not a valid frame
+ jetiExBusFrameState = EXBUS_STATE_ZERO;
+ jetiExBusRequestState = EXBUS_STATE_ZERO;
+ return;
+ }
+ }
+
+ // Done?
+ if (jetiExBusFrameLength == jetiExBusFramePosition) {
+ if (crc == 0){
+ if (jetiExBusFrameState == EXBUS_STATE_IN_PROGRESS) jetiExBusFrameState = EXBUS_STATE_RECEIVED;
+ if (jetiExBusRequestState == EXBUS_STATE_IN_PROGRESS) jetiExBusRequestState = EXBUS_STATE_RECEIVED;
+ }
+ jetiExBusFrameReset();
+ }
+}
+
+// Indicate time to read a frame from the data...
+uint8_t jetiExBusFrameStatus(void)
+{
+ if (jetiExBusFrameState == EXBUS_STATE_RECEIVED) {
+ jetiExBusDecodeFrame(&jetiExBusSerialFrame[0]);
+ jetiExBusFrameState = EXBUS_STATE_ZERO;
+ } else {
+ return SERIAL_RX_FRAME_PENDING;
+ }
+ return SERIAL_RX_FRAME_COMPLETE;
+}
+
+
+static uint16_t jetiExBusReadRawRC(rxRuntimeConfig_t *rxRuntimeConfig, uint8_t chan)
+{
+ if (chan >= rxRuntimeConfig->channelCount) return 0;
+
+ return (jetiExBusChannelData[chan]);
+}
+
+#ifdef TELEMETRY
+/*
+ -----------------------------------------------
+ Jeti Ex Bus Telemetry
+ -----------------------------------------------
+*/
+void createExTelemetrieTextMessage(uint8_t *exMessage, uint8_t messageID, const exBusSensor_t *Sensor)
+{
+ uint8_t labelLength = strlen(Sensor->name);
+ uint8_t unitLength = strlen(Sensor->unit);
+
+ jetiExTelemetry[EXTEL_HEADER_LSN_LB] = messageID & 0xF0;
+
+ exMessage[EXTEL_HEADER_TYPE_LEN] = 8 + labelLength + unitLength; // 7 header, 1 CRC, label & unit
+ exMessage[EXTEL_HEADER_ID] = messageID & 0x0F; // ExMessage ID
+ exMessage[EXTEL_HEADER_DATA] = (labelLength << 3) + unitLength;
+
+ memcpy(&exMessage[EXTEL_HEADER_DATA + 1], Sensor->name, labelLength);
+ memcpy(&exMessage[EXTEL_HEADER_DATA + 1 + labelLength], Sensor->unit, unitLength);
+
+ exMessage[exMessage[EXTEL_HEADER_TYPE_LEN] + 1] = calcCRC8(&exMessage[EXTEL_HEADER_TYPE_LEN], exMessage[EXTEL_HEADER_TYPE_LEN]);
+}
+
+uint8_t createExTelemetrieValueMessage(uint8_t *exMessage, uint8_t itemStart)
+{
+ if ((itemStart % 16) == 0) itemStart++;
+
+ uint8_t lastItem=itemStart + 5;
+
+ if (lastItem > JETI_EX_SENSOR_COUNT) lastItem = JETI_EX_SENSOR_COUNT;
+
+ jetiExTelemetry[EXTEL_HEADER_LSN_LB] = itemStart & 0xF0;
+
+ if (itemStart>JETI_EX_SENSOR_COUNT) return 0;
+
+ uint8_t byteCount = 0;
+ uint8_t valueByteCount = 0;
+
+ for (uint8_t item=itemStart; item < lastItem; item++){
+
+ switch(jetiExSensors[item].exDataType) {
+
+ case EX_TYPE_6b:
+ byteCount = 1;
+ break;
+ case EX_TYPE_14b:
+ byteCount = 2;
+ break;
+ case EX_TYPE_22b:
+ case EX_TYPE_DT:
+ byteCount = 3;
+ break;
+ case EX_TYPE_30b:
+ case EX_TYPE_GPS:
+ byteCount = 4;
+ break;
+ }
+
+ exMessage[EXTEL_HEADER_ID + valueByteCount] = ((item & 0xF) << 4) + jetiExSensors[item].exDataType;
+
+
+ uint32_t value = jetiExSensors[item].value;
+ if (jetiExSensors[item].value < 0) value &= resetMask[byteCount - 1];
+ value |= jetiExSensors[item].decimals;
+
+ uint8_t iCount = 0;
+ do {
+ exMessage[EXTEL_HEADER_DATA + valueByteCount + iCount] = value;
+ value = value>>8;
+ iCount++;
+ } while(iCount < byteCount);
+
+ valueByteCount += 1 + byteCount;
+ }
+
+ exMessage[EXTEL_HEADER_TYPE_LEN] = 0x46+valueByteCount;
+ exMessage[(exMessage[EXTEL_HEADER_TYPE_LEN] & 0x3F) + 1] = calcCRC8(&exMessage[EXTEL_HEADER_TYPE_LEN], (exMessage[EXTEL_HEADER_TYPE_LEN]&0x3F));
+
+ return lastItem;
+}
+
+
+
+void createExBusMessage(uint8_t *exBusMessage, uint8_t *exMessage, uint8_t exBusID)
+{
+ exBusMessage[EXBUS_HEADER_PACKET_ID] = exBusID;
+ exBusMessage[EXBUS_HEADER_SUBLEN] = (exMessage[EXTEL_HEADER_TYPE_LEN] & 0x3F) + 2; // +2: startbyte & CRC8
+ exBusMessage[EXBUS_HEADER_MSG_LEN] = 8 + exBusMessage[EXBUS_HEADER_SUBLEN];
+
+ uint16_t crc16 = calcCRC16(exBusMessage,exBusMessage[EXBUS_HEADER_MSG_LEN] - JETIEXBUS_CRC_LEN);
+ exBusMessage[exBusMessage[EXBUS_HEADER_MSG_LEN] - 2] = crc16;
+ exBusMessage[exBusMessage[EXBUS_HEADER_MSG_LEN] - 1] = crc16>>8;
+}
+
+
+
+void initJetiExBusTelemetry(telemetryConfig_t *initialTelemetryConfig)
+{
+ UNUSED(initialTelemetryConfig);
+
+ // Init Ex Bus Frame header
+ jetiExBusTelemetryFrame[EXBUS_HEADER_SYNC] = 0x3B; // Startbytes
+ jetiExBusTelemetryFrame[EXBUS_HEADER_REQ] = 0x01;
+ jetiExBusTelemetryFrame[EXBUS_HEADER_DATA_ID] = 0x3A; // Ex Telemetry
+
+
+ // Init Ex Telemetry header
+ jetiExTelemetry[EXTEL_HEADER_SYNC] = 0x9F; // Startbyte
+ jetiExTelemetry[EXTEL_HEADER_USN_LB] = 0x1E; // Serial Number 4 Byte
+ jetiExTelemetry[EXTEL_HEADER_USN_HB] = 0xA4;
+ jetiExTelemetry[EXTEL_HEADER_LSN_LB] = 0x00; // increment by telemetry count (%16) > only 15 values per device possible
+ jetiExTelemetry[EXTEL_HEADER_LSN_HB] = 0x00;
+ jetiExTelemetry[EXTEL_HEADER_RES] = 0x00; // Reserved by default 0x00
+
+ return;
+}
+
+
+void checkJetiExBusTelemetryState(void)
+{
+ return;
+}
+
+void handleJetiExBusTelemetry(void)
+{
+ if (jetiExBusRequestState == EXBUS_STATE_RECEIVED) {
+ jetiExSensors[EX_VOLTAGE].value = vbat;
+ jetiExSensors[EX_CURRENT].value = amperage;
+ jetiExSensors[EX_ALTITUDE].value = BaroAlt;
+ jetiExSensors[EX_CAPACITY].value = mAhDrawn;
+ // switch to TX mode
+ if (uartTotalRxBytesWaiting(jetiExBusPort) == 0) {
+ serialSetMode(jetiExBusPort, MODE_TX);
+ jetiExBusTransceiveState = EXBUS_TRANS_TX;
+ sendJetiExBusTelemetry(jetiExBusSerialFrame[JETIEXBUS_FRAME_OFFSET + EXBUS_HEADER_PACKET_ID]);
+ jetiExBusRequestState = EXBUS_STATE_PROCESSED;
+ }
+ }
+
+ // check the state if transmit is ready
+ if (jetiExBusTransceiveState == EXBUS_TRANS_TX_READY) {
+ uartPort_t *s = (uartPort_t*)jetiExBusPort;
+ if (uartTotalTxBytesFree(jetiExBusPort) == (s->port.txBufferSize - 1)) { // workaround for isUartTransmitBufferEmpty()
+ serialSetMode(jetiExBusPort, MODE_RX);
+ jetiExBusTransceiveState = EXBUS_TRANS_RX;
+ jetiExBusRequestState = EXBUS_STATE_ZERO;
+ }
+ }
+ return;
+}
+
+
+
+void sendJetiExBusTelemetry(uint8_t packetID)
+{
+ static uint8_t sensorDescriptionCounter = 0;
+ static uint8_t sensorValueCounter = 1;
+ static uint8_t requestLoop = 0;
+
+
+ if (requestLoop == 100){ //every n request send a name of a value
+ if (sensorDescriptionCounter == JETI_EX_SENSOR_COUNT ) sensorDescriptionCounter = 0;
+
+ createExTelemetrieTextMessage(jetiExTelemetry, sensorDescriptionCounter, &jetiExSensors[sensorDescriptionCounter]);
+ createExBusMessage(jetiExBusTelemetryFrame, jetiExTelemetry, packetID);
+ requestLoop = 0;
+ sensorDescriptionCounter++;
+
+ } else {
+ if (sensorValueCounter >= JETI_EX_SENSOR_COUNT) sensorValueCounter = 1;
+
+ sensorValueCounter = createExTelemetrieValueMessage(jetiExTelemetry, sensorValueCounter);
+ createExBusMessage(jetiExBusTelemetryFrame, jetiExTelemetry, packetID);
+ }
+
+ for (uint8_t iCount = 0; iCount < jetiExBusTelemetryFrame[EXBUS_HEADER_MSG_LEN]; iCount++) {
+ serialWrite(jetiExBusPort, jetiExBusTelemetryFrame[iCount]);
+ }
+ jetiExBusTransceiveState = EXBUS_TRANS_TX_READY;
+ requestLoop++;
+}
+
+#endif //TELEMETRY
diff --git a/src/main/rx/jetiexbus.h b/src/main/rx/jetiexbus.h
new file mode 100644
index 000000000..a975e5c64
--- /dev/null
+++ b/src/main/rx/jetiexbus.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of Cleanflight.
+ *
+ * Cleanflight 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.
+ *
+ * Cleanflight 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 Cleanflight. If not, see .
+ */
+
+#pragma once
+
+
+#include "rx/rx.h"
+
+bool jetiExBusInit(rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig, rcReadRawDataPtr *callback);
+uint8_t jetiExBusFrameStatus(void);
+
+
+#ifdef TELEMETRY
+
+#include "telemetry/telemetry.h"
+
+void initJetiExBusTelemetry(telemetryConfig_t *initialTelemetryConfig);
+void checkJetiExBusTelemetryState(void);
+void handleJetiExBusTelemetry(void);
+
+#endif //TELEMETRY
diff --git a/src/main/rx/rx.c b/src/main/rx/rx.c
index e2789f6d2..c4718f668 100644
--- a/src/main/rx/rx.c
+++ b/src/main/rx/rx.c
@@ -50,6 +50,7 @@
#include "rx/msp.h"
#include "rx/xbus.h"
#include "rx/ibus.h"
+#include "rx/jetiexbus.h"
#include "rx/rx.h"
@@ -240,6 +241,10 @@ void serialRxInit(rxConfig_t *rxConfig)
rxRefreshRate = 20000; // TODO - Verify speed
enabled = ibusInit(rxConfig, &rxRuntimeConfig, &rcReadRawFunc);
break;
+ case SERIALRX_JETIEXBUS:
+ rxRefreshRate = 5500;
+ enabled = jetiExBusInit(rxConfig, &rxRuntimeConfig, &rcReadRawFunc);
+ break;
}
if (!enabled) {
@@ -274,6 +279,8 @@ uint8_t serialRxFrameStatus(rxConfig_t *rxConfig)
return xBusFrameStatus();
case SERIALRX_IBUS:
return ibusFrameStatus();
+ case SERIALRX_JETIEXBUS:
+ return jetiExBusFrameStatus();
}
return SERIAL_RX_FRAME_PENDING;
}
diff --git a/src/main/rx/rx.h b/src/main/rx/rx.h
index 6ac43194c..d960d10ee 100644
--- a/src/main/rx/rx.h
+++ b/src/main/rx/rx.h
@@ -52,7 +52,8 @@ typedef enum {
SERIALRX_XBUS_MODE_B = 5,
SERIALRX_XBUS_MODE_B_RJ01 = 6,
SERIALRX_IBUS = 7,
- SERIALRX_PROVIDER_MAX = SERIALRX_IBUS
+ SERIALRX_JETIEXBUS = 8,
+ SERIALRX_PROVIDER_MAX = SERIALRX_JETIEXBUS
} SerialRXType;
#define SERIALRX_PROVIDER_COUNT (SERIALRX_PROVIDER_MAX + 1)
diff --git a/src/main/telemetry/telemetry.c b/src/main/telemetry/telemetry.c
index 4ac271390..4963d9df6 100644
--- a/src/main/telemetry/telemetry.c
+++ b/src/main/telemetry/telemetry.c
@@ -40,6 +40,7 @@
#include "telemetry/hott.h"
#include "telemetry/smartport.h"
#include "telemetry/ltm.h"
+#include "rx/jetiexbus.h"
static telemetryConfig_t *telemetryConfig;
@@ -54,7 +55,8 @@ void telemetryInit(void)
initHoTTTelemetry(telemetryConfig);
initSmartPortTelemetry(telemetryConfig);
initLtmTelemetry(telemetryConfig);
-
+ initJetiExBusTelemetry(telemetryConfig);
+
telemetryCheckState();
}
@@ -78,6 +80,7 @@ void telemetryCheckState(void)
checkHoTTTelemetryState();
checkSmartPortTelemetryState();
checkLtmTelemetryState();
+ checkJetiExBusTelemetryState();
}
void telemetryProcess(rxConfig_t *rxConfig, uint16_t deadband3d_throttle)
@@ -86,6 +89,7 @@ void telemetryProcess(rxConfig_t *rxConfig, uint16_t deadband3d_throttle)
handleHoTTTelemetry();
handleSmartPortTelemetry();
handleLtmTelemetry();
+ handleJetiExBusTelemetry();
}
#endif