diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index ac33c1cfc50..6a7f3e41bcc 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -192,6 +192,7 @@ enum TrainerMode { TRAINER_MODE_SLAVE, #if defined(PCBTARANIS) || defined(PCBNV14) TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, + TRAINER_MODE_MASTER_IBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, #endif #if defined(PCBTARANIS) || defined(AUX_SERIAL) || defined(AUX2_SERIAL) diff --git a/radio/src/ibus.cpp b/radio/src/ibus.cpp index 5d97d970115..ddb9086377f 100644 --- a/radio/src/ibus.cpp +++ b/radio/src/ibus.cpp @@ -1,14 +1,14 @@ #include "ibus.h" #include "opentx.h" +#include "trainer.h" #include #include -//#define IBUS_FRAME_GAP_DELAY 2000 // 1ms - -#define IBUS_VALUE_MIN 988 -#define IBUS_VALUE_MAX 2011 -#define IBUS_VALUE_CENTER 1500 +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic error "-Wswitch" // unfortunately the project uses -Wnoswitch +#endif namespace IBus { struct CheckSum final { @@ -16,7 +16,7 @@ namespace IBus { mSum = std::numeric_limits::max(); } inline uint8_t operator+=(const uint8_t b) { - mSum -= static_cast(b); + mSum -= b; return b; } inline uint8_t highByte() const { @@ -40,27 +40,27 @@ namespace IBus { uint16_t mSum = std::numeric_limits::max(); }; - uint16_t clamp(uint16_t v, uint16_t lower, uint16_t upper) { - return (v < lower) ? lower : ((v > upper) ? upper: v); - } - - int16_t convertIbusToPuls(uint16_t const ibusValue) { - const uint16_t clamped = clamp(ibusValue, IBUS_VALUE_MIN, IBUS_VALUE_MAX); - return (clamped - IBUS_VALUE_CENTER); - } struct Servo { + using IBus = Trainer::Protocol::IBus; + using MesgType = IBus::MesgType; + enum class State : uint8_t {Undefined, GotStart20, Data, CheckL, CheckH}; - static inline void process(const uint8_t b, std::function f) { - switch(mState) { + + static inline int16_t convertIbusToPuls(uint16_t const ibusValue) { + return Trainer::clamp(ibusValue - IBus::CenterValue); + } + + static inline void process(const uint8_t b, const std::function f) { + switch(mState) { // enum-switch -> no default (intentional) case State::Undefined: csum.reset(); - if (b == 0x20) { + if (b == IBus::StartByte1) { csum += b; mState = State::GotStart20; } break; case State::GotStart20: - if (b == 0x40) { + if (b == IBus::StartByte2) { csum += b; mState = State::Data; mIndex = 0; @@ -93,7 +93,7 @@ namespace IBus { break; } } - static inline void convert(int16_t* pulses) { + static inline void convert(int16_t* const pulses) { for (size_t chi{0}; chi < MAX_TRAINER_CHANNELS; chi++) { if (chi < 14) { const uint8_t h = ibusFrame[2 * chi + 1] & 0x0f; @@ -111,7 +111,6 @@ namespace IBus { } } private: - using MesgType = std::array; // 0x20, 0x40 , 28 Bytes, checkH, checkL static CheckSum csum; static State mState; static MesgType ibusFrame; @@ -139,3 +138,6 @@ void processIbusInput() { #endif } +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif diff --git a/radio/src/ibus.h b/radio/src/ibus.h index e2dcedd11c0..cd8493f828a 100644 --- a/radio/src/ibus.h +++ b/radio/src/ibus.h @@ -1,7 +1,6 @@ #pragma once #define IBUS_BAUDRATE 115200 -#define IBUS_FRAME_SIZE 32 void processIbusInput(); diff --git a/radio/src/sbus.cpp b/radio/src/sbus.cpp index 063cfda3d2f..eaeaae9b834 100644 --- a/radio/src/sbus.cpp +++ b/radio/src/sbus.cpp @@ -21,30 +21,23 @@ #include "opentx.h" #include "sbus.h" +#include "trainer.h" -#define SBUS_FRAME_GAP_DELAY 1000 // 500uS - -//#define SBUS_START_BYTE 0x0F -//#define SBUS_END_BYTE 0x00 -//#define SBUS_FLAGS_IDX 23 -#define SBUS_FRAMELOST_BIT 2 -#define SBUS_FAILSAFE_BIT 3 - -//#define SBUS_CH_BITS 11 -//#define SBUS_CH_MASK ((1<::value == (SBUS_FRAME_SIZE - 2), "consistency check"); + enum class State : uint8_t {Undefined, Data, GotEnd, WaitEnd}; static constexpr uint8_t mPauseCount{2}; // 2ms - - static constexpr uint8_t mFrameLostMask{1 << SBUS_FRAMELOST_BIT}; - static constexpr uint8_t mFailSafeMask{1 << SBUS_FAILSAFE_BIT}; - + static inline void tick1ms() { if (mPauseCounter > 0) { --mPauseCounter; @@ -53,25 +46,30 @@ namespace SBus { mState = State::Undefined; } } + + static inline int16_t convertSbusToPuls(uint16_t const sbusValue) { + const int16_t centered = sbusValue - SBus::CenterValue; + return Trainer::clamp((centered * 5) / 8); + } - static inline void process(const uint8_t b, std::function f) { + static inline void process(const uint8_t b, const std::function f) { mPauseCounter = mPauseCount; - switch(mState) { + switch(mState) { // enum-switch -> no default (intentional) case State::Undefined: - if (b == 0x00) { + if (b == SBus::EndByte) { mState = State::GotEnd; } - else if (b == 0x0f) { + else if (b == SBus::StartByte) { mState = State::Data; mIndex = 0; } break; case State::GotEnd: - if (b == 0x0f) { + if (b == SBus::StartByte) { mState = State::Data; mIndex = 0; } - else if (b == 0x00) { + else if (b == SBus::EndByte) { mState = State::GotEnd; } else { @@ -80,7 +78,7 @@ namespace SBus { break; case State::Data: mData[mIndex] = b; - if (mIndex >= (mData.size() - 1)) { + if (mIndex >= (mData.size() - 1)) { // got last byte mState = State::WaitEnd; } else { @@ -88,9 +86,10 @@ namespace SBus { } break; case State::WaitEnd: - if (b == 0x00) { + if (b == SBus::EndByte) { mState = State::GotEnd; - if (!((mData[mData.size() - 1] & mFrameLostMask) || (mData[mData.size() - 1] & mFailSafeMask))) { + uint8_t& statusByte = mData[mData.size() - 1]; // last byte + if (!((statusByte & SBus::FrameLostMask) || (statusByte & SBus::FailSafeMask))) { f(); ++mPackages; } @@ -100,74 +99,75 @@ namespace SBus { } break; } - } - static inline void convert(int16_t* pulses) { - pulses[0] = (uint16_t) (((mData[0] | mData[1] << 8)) & 0x07FF); - pulses[1] = (uint16_t) ((mData[1]>>3 | mData[2] <<5) & 0x07FF); - pulses[2] = (uint16_t) ((mData[2]>>6 | mData[3] <<2 |mData[4]<<10) & 0x07FF); - pulses[3] = (uint16_t) ((mData[4]>>1 | mData[5] <<7) & 0x07FF); - pulses[4] = (uint16_t) ((mData[5]>>4 | mData[6] <<4) & 0x07FF); - pulses[5] = (uint16_t) ((mData[6]>>7 | mData[7] <<1 |mData[8]<<9) & 0x07FF); - pulses[6] = (uint16_t) ((mData[8]>>2 | mData[9] <<6) & 0x07FF); - pulses[7] = (uint16_t) ((mData[9]>>5 | mData[10]<<3) & 0x07FF); - pulses[8] = (uint16_t) ((mData[11] | mData[12]<<8) & 0x07FF); - pulses[9] = (uint16_t) ((mData[12]>>3 | mData[13]<<5) & 0x07FF); - pulses[10] = (uint16_t) ((mData[13]>>6 | mData[14]<<2 |mData[15]<<10) & 0x07FF); - pulses[11] = (uint16_t) ((mData[15]>>1 | mData[16]<<7) & 0x07FF); - pulses[12] = (uint16_t) ((mData[16]>>4 | mData[17]<<4) & 0x07FF); - pulses[13] = (uint16_t) ((mData[17]>>7 | mData[18]<<1 |mData[19]<<9) & 0x07FF); - pulses[14] = (uint16_t) ((mData[19]>>2 | mData[20]<<6) & 0x07FF); - pulses[15] = (uint16_t) ((mData[20]>>5 | mData[21]<<3) & 0x07FF); + } + static inline void convert(int16_t* const pulses) { + static_assert(MAX_TRAINER_CHANNELS == 16); + pulses[0] = (uint16_t) (((mData[0] | mData[1] << 8)) & SBus::ValueMask); + pulses[1] = (uint16_t) ((mData[1]>>3 | mData[2] <<5) & SBus::ValueMask); + pulses[2] = (uint16_t) ((mData[2]>>6 | mData[3] <<2 | mData[4]<<10) & SBus::ValueMask); + pulses[3] = (uint16_t) ((mData[4]>>1 | mData[5] <<7) & SBus::ValueMask); + pulses[4] = (uint16_t) ((mData[5]>>4 | mData[6] <<4) & SBus::ValueMask); + pulses[5] = (uint16_t) ((mData[6]>>7 | mData[7] <<1 | mData[8]<<9) & SBus::ValueMask); + pulses[6] = (uint16_t) ((mData[8]>>2 | mData[9] <<6) & SBus::ValueMask); + pulses[7] = (uint16_t) ((mData[9]>>5 | mData[10]<<3) & SBus::ValueMask); + pulses[8] = (uint16_t) ((mData[11] | mData[12]<<8) & SBus::ValueMask); + pulses[9] = (uint16_t) ((mData[12]>>3 | mData[13]<<5) & SBus::ValueMask); + pulses[10] = (uint16_t) ((mData[13]>>6 | mData[14]<<2 | mData[15]<<10) & SBus::ValueMask); + pulses[11] = (uint16_t) ((mData[15]>>1 | mData[16]<<7) & SBus::ValueMask); + pulses[12] = (uint16_t) ((mData[16]>>4 | mData[17]<<4) & SBus::ValueMask); + pulses[13] = (uint16_t) ((mData[17]>>7 | mData[18]<<1 | mData[19]<<9) & SBus::ValueMask); + pulses[14] = (uint16_t) ((mData[19]>>2 | mData[20]<<6) & SBus::ValueMask); + pulses[15] = (uint16_t) ((mData[20]>>5 | mData[21]<<3) & SBus::ValueMask); - for(size_t i = 0; i < 16; ++i) { - pulses[i] -= SBUS_CH_CENTER; - pulses[i] *= 5; - pulses[i] /= 8; + for(size_t i = 0; i < MAX_TRAINER_CHANNELS; ++i) { + pulses[i] = convertSbusToPuls(pulses[i]); } } - using MesgType = std::array; + private: static State mState; static MesgType mData; static uint8_t mIndex; static uint16_t mPackages; static uint8_t mPauseCounter; }; - Servo::State Servo::mState{State::Undefined}; + Servo::State Servo::mState{Servo::State::Undefined}; Servo::MesgType Servo::mData; - uint8_t Servo::mIndex{}; - uint16_t Servo::mPackages{}; + uint8_t Servo::mIndex{0}; + uint16_t Servo::mPackages{0}; uint8_t Servo::mPauseCounter{Servo::mPauseCount}; // 2 ms } + void sbusTrainerPauseCheck() { #if !defined(SIMU) -// GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); - +# if defined(AUX_SERIAL) || defined(AUX2_SERIAL) || defined(TRAINER_MODULE_SBUS) if ((g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) - #ifdef AUX2_SERIAL + #if defined(AUX2_SERIAL) || (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) + #endif + #if defined(TRAINER_MODULE_SBUS) + || (g_model.trainerData.mode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE) #endif ) { SBus::Servo::tick1ms(); processSbusInput(); } -// GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); +# endif #endif } void processSbusInput() { #if !defined(SIMU) uint8_t rxchar; - -// GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); -// GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); - + while (sbusGetByte(&rxchar)) { SBus::Servo::process(rxchar, [&](){ -// GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); SBus::Servo::convert(ppmInput); ppmInputValidityTimer = PPM_IN_VALID_TIMEOUT; -// GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); }); } #endif } + +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 7edd1a968ca..44bfd02061b 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -174,6 +174,7 @@ void auxSerialSbusInit() { auxSerialInit(UART_MODE_SBUS_TRAINER, 0); } + void auxSerialIbusInit() { auxSerialInit(UART_MODE_IBUS_TRAINER, 0); @@ -371,13 +372,13 @@ void aux2SerialPutc(char c) USART_ITConfig(AUX2_SERIAL_USART, USART_IT_TXE, ENABLE); #endif } - + void aux2SerialSbusInit() { aux2SerialInit(UART_MODE_SBUS_TRAINER, 0); } void aux2SerialIbusInit() -{ +{ aux2SerialInit(UART_MODE_IBUS_TRAINER, 0); } diff --git a/radio/src/targets/horus/trainer_driver.cpp b/radio/src/targets/horus/trainer_driver.cpp index 0da609f7108..41a19a18c46 100644 --- a/radio/src/targets/horus/trainer_driver.cpp +++ b/radio/src/targets/horus/trainer_driver.cpp @@ -147,14 +147,14 @@ int sbusGetByte(uint8_t * byte) switch (currentTrainerMode) { #if defined(AUX_SERIAL) || defined(AUX2_SERIAL) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: -#if defined(AUX_SERIAL) +# if defined(AUX_SERIAL) if ((auxSerialMode == UART_MODE_SBUS_TRAINER) || (auxSerialMode == UART_MODE_IBUS_TRAINER)) return auxSerialRxFifo.pop(*byte); -#endif -#if defined(AUX2_SERIAL) +# endif +# if defined(AUX2_SERIAL) if ((aux2SerialMode == UART_MODE_SBUS_TRAINER) || (aux2SerialMode == UART_MODE_IBUS_TRAINER)) return aux2SerialRxFifo.pop(*byte); -#endif +# endif #endif default: return false; diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 1c8a55c8427..2397f8fff3c 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -190,9 +190,11 @@ void extmoduleSendInvertedByte(uint8_t byte); #endif #if defined(TRAINER_MODULE_SBUS) void init_trainer_module_sbus(); + void init_trainer_module_ibus(); void stop_trainer_module_sbus(); #else #define init_trainer_module_sbus() + #define init_trainer_module_ibus() #define stop_trainer_module_sbus() #endif diff --git a/radio/src/targets/taranis/trainer_driver.cpp b/radio/src/targets/taranis/trainer_driver.cpp index a78d9c90677..895052b2925 100644 --- a/radio/src/targets/taranis/trainer_driver.cpp +++ b/radio/src/targets/taranis/trainer_driver.cpp @@ -284,9 +284,9 @@ void init_trainer_module_sbus() GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(TRAINER_MODULE_SBUS_GPIO, &GPIO_InitStructure); - USART_InitStructure.USART_BaudRate = 100000; + USART_InitStructure.USART_BaudRate = SBUS_BAUDRATE; USART_InitStructure.USART_WordLength = USART_WordLength_9b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_StopBits = USART_StopBits_1; // this should be 2 stop bits USART_InitStructure.USART_Parity = USART_Parity_Even; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx; @@ -317,6 +317,55 @@ void init_trainer_module_sbus() DMA_Cmd(TRAINER_MODULE_SBUS_DMA_STREAM, ENABLE); } +void init_trainer_module_ibus() +{ + EXTERNAL_MODULE_ON(); + + USART_InitTypeDef USART_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_PinAFConfig(TRAINER_MODULE_SBUS_GPIO, TRAINER_MODULE_SBUS_GPIO_PinSource, TRAINER_MODULE_SBUS_GPIO_AF); + + GPIO_InitStructure.GPIO_Pin = TRAINER_MODULE_SBUS_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_Init(TRAINER_MODULE_SBUS_GPIO, &GPIO_InitStructure); + + USART_InitStructure.USART_BaudRate = IBUS_BAUDRATE; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx; + USART_Init(TRAINER_MODULE_SBUS_USART, &USART_InitStructure); + + DMA_InitTypeDef DMA_InitStructure; + trainerSbusFifo.clear(); + USART_ITConfig(TRAINER_MODULE_SBUS_USART, USART_IT_RXNE, DISABLE); + USART_ITConfig(TRAINER_MODULE_SBUS_USART, USART_IT_TXE, DISABLE); + DMA_InitStructure.DMA_Channel = TRAINER_MODULE_SBUS_DMA_CHANNEL; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TRAINER_MODULE_SBUS_USART->DR); + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(trainerSbusFifo.buffer()); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = trainerSbusFifo.size(); + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_Low; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TRAINER_MODULE_SBUS_DMA_STREAM, &DMA_InitStructure); + USART_DMACmd(TRAINER_MODULE_SBUS_USART, USART_DMAReq_Rx, ENABLE); + USART_Cmd(TRAINER_MODULE_SBUS_USART, ENABLE); + DMA_Cmd(TRAINER_MODULE_SBUS_DMA_STREAM, ENABLE); +} + void stop_trainer_module_sbus() { DMA_Cmd(TRAINER_MODULE_SBUS_DMA_STREAM, DISABLE); diff --git a/radio/src/tasks.cpp b/radio/src/tasks.cpp index e38ae15ad27..5cdbc385396 100644 --- a/radio/src/tasks.cpp +++ b/radio/src/tasks.cpp @@ -117,17 +117,16 @@ constexpr uint8_t MIXER_MAX_PERIOD = MAX_REFRESH_RATE / 1000 /*ms*/; void execMixerFrequentActions() { -#if defined(SBUS_TRAINER) - // SBUS trainer +#if defined(SBUS_TRAINER) && (defined(AUX_SERIAL) || defined(AUX2_SERIAL)) if ((g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) - #ifdef AUX2_SERIAL + #if defined(AUX2_SERIAL) || (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) #endif ) { processSbusInput(); } else if ((g_eeGeneral.auxSerialMode == UART_MODE_IBUS_TRAINER) - #ifdef AUX2_SERIAL + #if defined(AUX2_SERIAL) || (g_eeGeneral.aux2SerialMode == UART_MODE_IBUS_TRAINER) #endif ) { diff --git a/radio/src/trainer.cpp b/radio/src/trainer.cpp index 636bf7dc7c3..68b312bdc79 100644 --- a/radio/src/trainer.cpp +++ b/radio/src/trainer.cpp @@ -20,6 +20,7 @@ */ #include "opentx.h" +#include "trainer.h" int16_t ppmInput[MAX_TRAINER_CHANNELS]; uint8_t ppmInputValidityTimer; @@ -114,36 +115,34 @@ void checkTrainerSettings() case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: init_trainer_module_sbus(); break; + case TRAINER_MODE_MASTER_IBUS_EXTERNAL_MODULE: + init_trainer_module_ibus(); + break; #endif #if defined(TRAINER_BATTERY_COMPARTMENT) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: -#if defined(AUX_SERIAL) +#if defined(AUX_SERIAL) && !defined(SIMU) if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) { auxSerialSbusInit(); break; } if (g_eeGeneral.auxSerialMode == UART_MODE_IBUS_TRAINER) { -#ifndef SIMU auxSerialIbusInit(); -#endif break; } #endif -#if defined(AUX2_SERIAL) +#if defined(AUX2_SERIAL) && !defined(SIMU) if (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) { aux2SerialSbusInit(); break; } if (g_eeGeneral.aux2SerialMode == UART_MODE_IBUS_TRAINER) { -#ifndef SIMU aux2SerialIbusInit(); -#endif break; } #endif - // no break #endif diff --git a/radio/src/trainer.h b/radio/src/trainer.h index 9a81901a5cc..d1b6648b841 100644 --- a/radio/src/trainer.h +++ b/radio/src/trainer.h @@ -24,6 +24,42 @@ #include "dataconstants.h" +namespace Trainer { + static constexpr int16_t MaxValue = +512; + static constexpr int16_t MinValue = -512; + + static inline int16_t clamp(int16_t const v) { + return (v < MinValue) ? MinValue : ((v > MaxValue) ? MaxValue : v); + } + + namespace Protocol { + struct SBus { + using MesgType = std::array; + + static constexpr uint8_t ValueBits = 11; + static constexpr uint16_t ValueMask = ((1 << ValueBits) - 1); + + static constexpr uint8_t FrameLostBit = 2; + static constexpr uint8_t FailSafeBit = 3; + static constexpr uint8_t StartByte = 0x0f; + static constexpr uint8_t EndByte = 0x00; + static constexpr uint8_t FrameLostMask{1 << FrameLostBit}; + static constexpr uint8_t FailSafeMask{1 << FailSafeBit}; + + static constexpr uint16_t CenterValue = 0x3e0; + }; + struct IBus { + using MesgType = std::array; // 0x20, 0x40 , 28 Bytes, checkH, checkL + + static constexpr uint8_t StartByte1 = 0x20; + static constexpr uint8_t StartByte2 = 0x40; + static constexpr uint16_t MaxValue = 988; + static constexpr uint16_t MinValue = 2011; + static constexpr uint16_t CenterValue = (MaxValue + MinValue) / 2; + }; + } +} + // Trainer input channels extern int16_t ppmInput[MAX_TRAINER_CHANNELS]; diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index 5031592e4ef..14aaaba5286 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -89,7 +89,7 @@ #elif defined(PCBHORUS) #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBTARANIS) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_IBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #else #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #endif