diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 9135efe848b..e2a0773c602 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -679,8 +679,8 @@ PACK(struct ModuleData { uint8_t receiver_telem_off:1; // false = receiver telem enabled uint8_t receiver_channel_9_16:1; // false = pwm out 1-8, true 9-16 uint8_t external_antenna:1; // false = internal antenna, true = external antenna - uint8_t spare2:1; - uint8_t spare3; + uint8_t fast:1; // TODO: to be used later by external module (fast means serial @ high speed) + uint8_t spare2; } pxx); NOBACKUP(struct { uint8_t spare1:6; diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index abe8596f030..58b5b9f23f4 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -48,7 +48,7 @@ #endif #define GET_PPM_POLARITY(idx) g_model.moduleData[idx].ppm.pulsePol -#define GET_SBUS_POLARITY(idx) g_model.moduleData[idx].sbus.noninverted +#define GET_SBUS_POLARITY(idx) g_model.moduleData[idx].sbus.noninverted #define GET_PPM_DELAY(idx) (g_model.moduleData[idx].ppm.delay * 50 + 300) #define SET_DEFAULT_PPM_FRAME_LENGTH(idx) g_model.moduleData[idx].ppm.frameLength = 4 * max((int8_t)0, g_model.moduleData[idx].channelsCount) diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 684d3548362..6328e10821d 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -702,7 +702,7 @@ extern uint8_t flightModeTransitionLast; void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms); void evalMixes(uint8_t tick10ms); void doMixerCalculations(); -void scheduleNextMixerCalculation(uint8_t module, uint16_t delay); +void scheduleNextMixerCalculation(uint8_t module, uint16_t period_ms); #if defined(CPUARM) void checkTrims(); diff --git a/radio/src/pulses/dsm2_arm.cpp b/radio/src/pulses/dsm2_arm.cpp index b240e33babe..99b6506b0bb 100644 --- a/radio/src/pulses/dsm2_arm.cpp +++ b/radio/src/pulses/dsm2_arm.cpp @@ -35,7 +35,38 @@ uint8_t dsm2BindTimer = DSM2_BIND_TIMEOUT; #define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit -#if !defined(PPM_PIN_SERIAL) +#if defined(PPM_PIN_SERIAL) +void putDsm2SerialBit(uint8_t bit) +{ + modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte >>= 1; + if (bit & 1) { + modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte |= 0x80; + } + if (++modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount >= 8) { + *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte; + modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0; + } +} + +void sendByteDsm2(uint8_t b) // max 10changes 0 10 10 10 10 1 +{ + putDsm2SerialBit(0); // Start bit + for (uint8_t i=0; i<8; i++) { // 8 data Bits + putDsm2SerialBit(b & 1); + b >>= 1; + } + + putDsm2SerialBit(1); // Stop bit + putDsm2SerialBit(1); // Stop bit +} + +void putDsm2Flush() +{ + for (int i=0; i<16; i++) { + putDsm2SerialBit(1); // 16 extra stop bits + } +} +#else void _send_1(uint8_t v) { if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1) @@ -74,37 +105,6 @@ void putDsm2Flush() else *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) = modulePulsesData[EXTERNAL_MODULE].dsm2.rest; } -#else -void putDsm2SerialBit(uint8_t bit) -{ - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte >>= 1; - if (bit & 1) { - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte |= 0x80; - } - if (++modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount >= 8) { - *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte; - modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0; - } -} - -void sendByteDsm2(uint8_t b) // max 10changes 0 10 10 10 10 1 -{ - putDsm2SerialBit(0); // Start bit - for (uint8_t i=0; i<8; i++) { // 8 data Bits - putDsm2SerialBit(b & 1); - b >>= 1; - } - - putDsm2SerialBit(1); // Stop bit - putDsm2SerialBit(1); // Stop bit -} - -void putDsm2Flush() -{ - for (int i=0; i<16; i++) { - putDsm2SerialBit(1); // 16 extra stop bits - } -} #endif // This is the data stream to send, prepare after 19.5 mS @@ -119,7 +119,7 @@ void setupPulsesDSM2(uint8_t port) modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ; #else modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0; - modulePulsesData[EXTERNAL_MODULE].dsm2.rest = 44000; + modulePulsesData[EXTERNAL_MODULE].dsm2.rest = DSM2_PERIOD * 2000; #endif modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; diff --git a/radio/src/pulses/multi_arm.cpp b/radio/src/pulses/multi_arm.cpp index a25fbe7b932..df12c8e259d 100644 --- a/radio/src/pulses/multi_arm.cpp +++ b/radio/src/pulses/multi_arm.cpp @@ -24,15 +24,12 @@ // see https://github.com/pascallanger/DIY-Multiprotocol-TX-Module // file Multiprotocol/multiprotocol.h - - #define MULTI_SEND_BIND (1 << 7) #define MULTI_SEND_RANGECHECK (1 << 5) #define MULTI_SEND_AUTOBIND (1 << 6) - -#define MULTI_CHANS 16 -#define MULTI_CHAN_BITS 11 +#define MULTI_CHANS 16 +#define MULTI_CHAN_BITS 11 static void sendFrameProtocolHeader(uint8_t port, bool failsafe); @@ -40,15 +37,15 @@ void sendChannels(uint8_t port); static void sendSetupFrame() { - // Old multi firmware will mark config messsages as invalid frame and throw them away sendByteSbus('M'); sendByteSbus('P'); - sendByteSbus(0x80); // Module Configuration - sendByteSbus(1); // 1 byte data - uint8_t config = 0x1 | 0x2; // inversion + multi_telemetry + sendByteSbus(0x80); // Module Configuration + sendByteSbus(1); // 1 byte data + uint8_t config = 0x01 | 0x02; // inversion + multi_telemetry #if !defined(PPM_PIN_SERIAL) - config |= 0x04; //input synchronsisation + // TODO why PPM_PIN_SERIAL would change MULTI protocol? + config |= 0x04; // input synchronsisation #endif sendByteSbus(config); @@ -68,7 +65,6 @@ static void sendFailsafeChannels(uint8_t port) if (g_model.moduleData[port].failsafeMode == FAILSAFE_NOPULSES) failsafeValue = FAILSAFE_CHANNEL_NOPULSE; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { pulseValue = 0; } @@ -87,13 +83,13 @@ static void sendFailsafeChannels(uint8_t port) bits >>= 8; bitsavailable -= 8; } - } } void setupPulsesMultimodule(uint8_t port) { - static int counter=0; + static int counter = 0; + #if defined(PPM_PIN_SERIAL) modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ; modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ; diff --git a/radio/src/pulses/pulses_arm.cpp b/radio/src/pulses/pulses_arm.cpp index f92a9b2e9ad..f2135ed0b07 100755 --- a/radio/src/pulses/pulses_arm.cpp +++ b/radio/src/pulses/pulses_arm.cpp @@ -136,7 +136,7 @@ void setupPulses(uint8_t port) case PROTO_DSM2_LP45: case PROTO_DSM2_DSM2: case PROTO_DSM2_DSMX: - disable_dsm2(port); + disable_serial(port); break; #endif @@ -150,7 +150,7 @@ void setupPulses(uint8_t port) case PROTO_MULTIMODULE: #endif case PROTO_SBUS: - disable_sbusOut(port); + disable_serial(port); break; case PROTO_PPM: @@ -168,11 +168,12 @@ void setupPulses(uint8_t port) switch (required_protocol) { case PROTO_PXX: setupPulsesPXX(port); - scheduleNextMixerCalculation(port, MODULES_TIMER_PXX_PERIOD); + scheduleNextMixerCalculation(port, PXX_PERIOD); break; + case PROTO_SBUS: setupPulsesSbus(port); - scheduleNextMixerCalculation(port, (45+g_model.moduleData[port].sbus.refreshRate)/2); + scheduleNextMixerCalculation(port, SBUS_PERIOD); break; #if defined(DSM2) @@ -180,7 +181,7 @@ void setupPulses(uint8_t port) case PROTO_DSM2_DSM2: case PROTO_DSM2_DSMX: setupPulsesDSM2(port); - scheduleNextMixerCalculation(port, 11); + scheduleNextMixerCalculation(port, DSM2_PERIOD); break; #endif @@ -203,14 +204,14 @@ void setupPulses(uint8_t port) } sportSendBuffer(crossfire, len); } - scheduleNextMixerCalculation(port, CROSSFIRE_FRAME_PERIOD); + scheduleNextMixerCalculation(port, CROSSFIRE_PERIOD); break; #endif #if defined(MULTIMODULE) case PROTO_MULTIMODULE: setupPulsesMultimodule(port); - scheduleNextMixerCalculation(port, 4); + scheduleNextMixerCalculation(port, MULTIMODULE_PERIOD); break; #endif @@ -219,7 +220,7 @@ void setupPulses(uint8_t port) case PROTO_NONE: #endif setupPulsesPPMModule(port); - scheduleNextMixerCalculation(port, (45+g_model.moduleData[port].ppm.frameLength)/2); + scheduleNextMixerCalculation(port, PPM_PERIOD(port)); break; default: @@ -236,7 +237,7 @@ void setupPulses(uint8_t port) case PROTO_DSM2_LP45: case PROTO_DSM2_DSM2: case PROTO_DSM2_DSMX: - init_dsm2(port); + init_serial(port, DSM2_BAUDRATE, DSM2_PERIOD * 2000); break; #endif @@ -248,12 +249,14 @@ void setupPulses(uint8_t port) #if defined(MULTIMODULE) case PROTO_MULTIMODULE: + init_serial(port, MULTIMODULE_BAUDRATE, MULTIMODULE_PERIOD * 2000); + break; #endif + case PROTO_SBUS: - init_sbusOut(port); + init_serial(port, SBUS_BAUDRATE, SBUS_PERIOD_HALF_US); break; - case PROTO_PPM: init_ppm(port); break; diff --git a/radio/src/pulses/pulses_arm.h b/radio/src/pulses/pulses_arm.h index 7a955884aa2..f3705b3c267 100644 --- a/radio/src/pulses/pulses_arm.h +++ b/radio/src/pulses/pulses_arm.h @@ -47,13 +47,15 @@ template struct PpmPulsesData { #if defined(PXX_FREQUENCY_HIGH) #define EXTMODULE_USART_PXX_BAUDRATE 420000 #define INTMODULE_USART_PXX_BAUDRATE 450000 -#define MODULES_TIMER_PXX_PERIOD 4 // 4ms +#define PXX_PERIOD 4/*ms*/ #else #define EXTMODULE_USART_PXX_BAUDRATE 115200 #define INTMODULE_USART_PXX_BAUDRATE 115200 -#define MODULES_TIMER_PXX_PERIOD 9 // 9ms +#define PXX_PERIOD 9/*ms*/ #endif +#define PXX_PERIOD_HALF_US (PXX_PERIOD * 2000) + #if defined(PPM_PIN_SERIAL) PACK(struct PxxSerialPulsesData { uint8_t pulses[64]; @@ -64,7 +66,9 @@ PACK(struct PxxSerialPulsesData { uint16_t serialByte; uint16_t serialBitCount; }); +#endif +#if defined(PPM_PIN_SERIAL) PACK(struct Dsm2SerialPulsesData { uint8_t pulses[64]; uint8_t * ptr; @@ -72,6 +76,14 @@ PACK(struct Dsm2SerialPulsesData { uint8_t serialBitCount; uint16_t _alignment; }); +#else +#define MAX_PULSES_TRANSITIONS 300 +PACK(struct Dsm2TimerPulsesData { + pulse_duration_t pulses[MAX_PULSES_TRANSITIONS]; + pulse_duration_t * ptr; + uint16_t rest; + uint8_t index; +}); #endif #if defined(INTMODULE_USART) || defined(EXTMODULE_USART) @@ -83,9 +95,17 @@ PACK(struct PxxUartPulsesData { }); #endif -#define MULTIMODULE_BAUDRATE 100000 -#if defined(INTMODULE_PULSES) || defined(EXTMODULE_PULSES) - +#define PPM_PERIOD_HALF_US(module) ((g_model.moduleData[module].ppm.frameLength * 5 + 225) * 200) /*half us*/ +#define PPM_PERIOD(module) (PPM_PERIOD_HALF_US(module) / 2000) /*ms*/ +#define DSM2_BAUDRATE 125000 +#define DSM2_PERIOD 22 /*ms*/ +#define SBUS_BAUDRATE 100000 +#define SBUS_PERIOD_HALF_US ((g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225) * 200) /*half us*/ +#define SBUS_PERIOD (SBUS_PERIOD_HALF_US / 2000) /*ms*/ +#define MULTIMODULE_BAUDRATE 100000 +#define MULTIMODULE_PERIOD 7 /*ms*/ + +#if !defined(EXTMODULE_USART) || !defined(EXTMODULE_USART) /* PXX uses 20 bytes (as of Rev 1.1 document) with 8 changes per byte + stop bit ~= 162 max pulses */ /* DSM2 uses 2 header + 12 channel bytes, with max 10 changes (8n2) per byte + 16 bits trailer ~= 156 max pulses */ /* Multimodule uses 3 bytes header + 22 channel bytes with max 11 changes per byte (8e2) + 16 bits trailer ~= 291 max pulses */ @@ -103,15 +123,6 @@ PACK(struct PxxTimerPulsesData { uint16_t pcmCrc; uint32_t pcmOnesCount; }); - -#define MAX_PULSES_TRANSITIONS 300 - -PACK(struct Dsm2TimerPulsesData { - pulse_duration_t pulses[MAX_PULSES_TRANSITIONS]; - pulse_duration_t * ptr; - uint16_t rest; - uint8_t index; -}); #endif #define CROSSFIRE_FRAME_MAXLEN 64 @@ -121,17 +132,21 @@ PACK(struct CrossfirePulsesData { }); union ModulePulsesData { +#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) + PxxUartPulsesData pxx_uart; +#endif #if defined(PPM_PIN_SERIAL) PxxSerialPulsesData pxx; - Dsm2SerialPulsesData dsm2; -#endif -#if defined(INTMODULE_PULSES) || defined(EXTMODULE_PULSES) +#elif !defined(INTMODULE_USART) || !defined(EXTMODULE_USART) PxxTimerPulsesData pxx; - Dsm2TimerPulsesData dsm2; #endif -#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) - PxxUartPulsesData pxx_uart; + +#if defined(PPM_PIN_SERIAL) + Dsm2SerialPulsesData dsm2; +#else + Dsm2TimerPulsesData dsm2; #endif + PpmPulsesData ppm; CrossfirePulsesData crossfire; } __ALIGNED; diff --git a/radio/src/pulses/pxx_arm.cpp b/radio/src/pulses/pxx_arm.cpp index 480377e0f79..29944653d20 100644 --- a/radio/src/pulses/pxx_arm.cpp +++ b/radio/src/pulses/pxx_arm.cpp @@ -106,6 +106,8 @@ void uartPutPcmCrc(uint8_t port) } #endif +#if !defined(INTMODULE_USART) || !defined(EXTMODULE_USART) + #if defined(PPM_PIN_SERIAL) void pxxPutPcmSerialBit(uint8_t port, uint8_t bit) { @@ -180,7 +182,7 @@ void pxxInitPcmArray(uint8_t port) #if defined(PPM_PIN_SERIAL) modulePulsesData[port].pxx.pcmValue = 0; #else - modulePulsesData[port].pxx.rest = 18000; + modulePulsesData[port].pxx.rest = PXX_PERIOD_HALF_US; #endif modulePulsesData[port].pxx.pcmOnesCount = 0; @@ -211,6 +213,15 @@ void pxxPutPcmCrc(uint8_t port) pxxPutPcmByte(port, pulseValue >> 8); pxxPutPcmByte(port, pulseValue); } +#else + // those functions should not be used, a link error will occur if wrong + void pxxInitPcmArray(uint8_t port); + void pxxInitPcmCrc(uint8_t port); + void pxxPutPcmByte(uint8_t port, uint8_t byte); + void pxxPutPcmHead(uint8_t port); + void pxxPutPcmTail(uint8_t port); + void pxxPutPcmCrc(uint8_t port); +#endif #if defined(INTMODULE_USART) || defined(EXTMODULE_USART) inline void initPcmArray(uint8_t port) diff --git a/radio/src/pulses/sbus_arm.cpp b/radio/src/pulses/sbus_arm.cpp index e3f841d2e21..5824f17fe2f 100644 --- a/radio/src/pulses/sbus_arm.cpp +++ b/radio/src/pulses/sbus_arm.cpp @@ -21,7 +21,7 @@ #include "opentx.h" -#define BITLEN_SBUS (10*2) //100000 Baud => 10uS per bit +#define BITLEN_SBUS (10*2) // 100000 Baud => 10uS per bit /* The protocol reuse some the DSM2 definitions where they are identical */ @@ -84,8 +84,6 @@ void sendByteSbus(uint8_t b) //max 11 changes 0 10 10 10 10 P 1 #endif - - #define SBUS_NORMAL_CHANS 16 #define SBUS_CHAN_BITS 11 @@ -100,27 +98,27 @@ void sendByteSbus(uint8_t b) //max 11 changes 0 10 10 10 10 P 1 #define SBUS_CHAN_CENTER 992 -inline int getChannelValue(uint8_t port, int channel) { +inline int getChannelValue(uint8_t port, int channel) +{ int ch = g_model.moduleData[port].channelsStart+channel; // We will ignore 17 and 18th if that brings us over the limit if (ch > 31) return 0; - return channelOutputs[ch] + 2*PPM_CH_CENTER(ch) - 2*PPM_CENTER; + return channelOutputs[ch] + 2 * PPM_CH_CENTER(ch) - 2*PPM_CENTER; } void setupPulsesSbus(uint8_t port) { #if defined(PPM_PIN_SERIAL) - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ; - modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ; + modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0; + modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0; #else - modulePulsesData[EXTERNAL_MODULE].dsm2.rest = (g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225)*200 ; + modulePulsesData[EXTERNAL_MODULE].dsm2.rest = SBUS_PERIOD_HALF_US; modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0; #endif modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; - // Sync Byte sendByteSbus(SBUS_FRAME_BEGIN_BYTE); @@ -140,7 +138,8 @@ void setupPulsesSbus(uint8_t port) bitsavailable -= 8; } } - // Flags + + // flags uint8_t flags=0; if (getChannelValue(port, 16) > 0) flags |=SBUS_FLAG_CHANNEL_17; @@ -149,7 +148,7 @@ void setupPulsesSbus(uint8_t port) sendByteSbus(flags); - // Last byte, always 0x0 + // last byte, always 0x0 sendByteSbus(0x0); putDsm2Flush(); diff --git a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp index ff4c3551d89..dbefcf1703c 100755 --- a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp @@ -98,8 +98,8 @@ void intmodulePxxStart() // Timer INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - INTMODULE_TIMER->ARR = 2000 * MODULES_TIMER_PXX_PERIOD; - INTMODULE_TIMER->CCR2 = (2000 * MODULES_TIMER_PXX_PERIOD) - 2000; // Update time + INTMODULE_TIMER->ARR = PXX_PERIOD_HALF_US; + INTMODULE_TIMER->CCR2 = PXX_PERIOD_HALF_US - 2000; // Update time INTMODULE_TIMER->CCER = TIM_CCER_CC3E; INTMODULE_TIMER->CCMR2 = 0; INTMODULE_TIMER->EGR = 1; // Restart diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 220059a492a..706ef48fe86 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -196,12 +196,10 @@ void init_ppm(uint32_t module_index); void disable_ppm(uint32_t module_index); void init_pxx(uint32_t module_index); void disable_pxx(uint32_t module_index); -void init_dsm2(uint32_t module_index); -void disable_dsm2(uint32_t module_index); +void init_serial(uint32_t module_index, uint32_t baudrate, uint32_t period_half_us); +void disable_serial(uint32_t module_index); void init_crossfire(uint32_t module_index); void disable_crossfire(uint32_t module_index); -void init_sbusOut(uint32_t module_index); -void disable_sbusOut(uint32_t module_index); // Trainer driver void init_trainer_ppm(void); diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index 0b369bab058..10e86cf5836 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -162,7 +162,7 @@ void extmodulePxxStart() } #if defined(DSM2) -void extmoduleDsm2Start() +void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us) { EXTERNAL_MODULE_ON(); @@ -178,7 +178,7 @@ void extmoduleDsm2Start() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = 44000; // 22mS + EXTMODULE_TIMER->ARR = period_half_us; #if defined(PCBX10) || PCBREV >= 13 EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3P; @@ -226,8 +226,8 @@ void extmoduleCrossfireStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_FRAME_PERIOD); - EXTMODULE_TIMER->CCR2 = (2000 * CROSSFIRE_FRAME_PERIOD) - 1000; + EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_PERIOD); + EXTMODULE_TIMER->CCR2 = (2000 * CROSSFIRE_PERIOD) - 1000; EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt diff --git a/radio/src/targets/horus/pulses_driver.cpp b/radio/src/targets/horus/pulses_driver.cpp index 096de56da3c..be46b31b890 100644 --- a/radio/src/targets/horus/pulses_driver.cpp +++ b/radio/src/targets/horus/pulses_driver.cpp @@ -29,9 +29,7 @@ void intmodulePxxStart(void); void extmoduleNoneStart(void); void extmodulePpmStart(void); void extmodulePxxStart(void); -#if defined(DSM2) -void extmoduleDsm2Start(void); -#endif +void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us); void extmoduleCrossfireStart(void); void init_no_pulses(uint32_t port) @@ -81,14 +79,14 @@ void disable_pxx(uint32_t port) } #if defined(DSM2) -void init_dsm2(uint32_t port) +void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us) { if (port == EXTERNAL_MODULE) { - extmoduleDsm2Start(); + extmoduleSerialStart(baudrate, period_half_us); } } -void disable_dsm2(uint32_t port) +void disable_serial(uint32_t port) { if (port == EXTERNAL_MODULE) { extmoduleStop(); @@ -96,16 +94,6 @@ void disable_dsm2(uint32_t port) } #endif -void init_sbusOut(uint32_t port) -{ - init_dsm2(port); -} - -void disable_sbusOut(uint32_t port) -{ - disable_dsm2(port); -} - void init_crossfire(uint32_t port) { if (port == EXTERNAL_MODULE) { diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index ed8a568f7d1..c526ddddffd 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -262,11 +262,8 @@ void init_ppm(uint32_t port); void disable_ppm(uint32_t port); void init_pxx(uint32_t port); void disable_pxx(uint32_t port); -void init_dsm2(uint32_t port); -void disable_dsm2(uint32_t port); - -void init_sbusOut(uint32_t module_index); -void disable_sbusOut(uint32_t module_index); +void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us); +void disable_serial(uint32_t port); // SD driver #if defined(SIMU) diff --git a/radio/src/targets/sky9x/pulses_driver.cpp b/radio/src/targets/sky9x/pulses_driver.cpp index be6156f1249..838eec84abc 100644 --- a/radio/src/targets/sky9x/pulses_driver.cpp +++ b/radio/src/targets/sky9x/pulses_driver.cpp @@ -222,18 +222,25 @@ void disable_pxx(uint32_t port) } } -void init_dsm2(uint32_t port) +void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us) { if (port == EXTERNAL_MODULE) { - init_main_ppm(2500 * 2, 0); - init_ssc(125); + if (baudrate == 125000) { + // TODO init_main_ppm could take the period as parameter? + init_main_ppm(2500 * 2, 0); + init_ssc(125); + } + else { + init_main_ppm(3500 * 2, 0); + init_ssc(100); + } } else { // TODO } } -void disable_dsm2(uint32_t port) +void disable_serial(uint32_t port) { if (port == EXTERNAL_MODULE) { disable_ssc(); @@ -244,22 +251,6 @@ void disable_dsm2(uint32_t port) } } -void init_sbusOut(uint32_t port) -{ - if (port == EXTERNAL_MODULE) { - init_main_ppm(3500 * 2, 0); - init_ssc(100); - } - else { - // TODO - } -} - -void disable_sbusOut(uint32_t port) -{ - disable_dsm2(port); -} - #if !defined(SIMU) extern "C" void PWM_IRQHandler(void) { diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index c1e3fe61c6b..8c22592af01 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -76,7 +76,7 @@ elseif(PCB STREQUAL X7) set(LCD_DRIVER lcd_driver_spi.cpp) set(GVAR_SCREEN model_gvars.cpp) elseif(PCB STREQUAL XLITE) - option(PXX_FREQUENCY "PXX Frequency (LOW / HIGH)" HIGH) + set(PXX_FREQUENCY "HIGH" CACHE STRING "PXX frequency (LOW / HIGH)") set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F2) set(CPU_TYPE_FULL STM32F205xE) # for size report diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 2d3e4c44171..d5765e0abac 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -189,12 +189,10 @@ void init_ppm( uint32_t module_index ); void disable_ppm( uint32_t module_index ); void init_pxx( uint32_t module_index ); void disable_pxx( uint32_t module_index ); -void init_dsm2( uint32_t module_index ); -void disable_dsm2( uint32_t module_index ); +void init_serial( uint32_t module_index, uint32_t baudrate, uint32_t period ); +void disable_serial( uint32_t module_index ); void init_crossfire( uint32_t module_index ); void disable_crossfire( uint32_t module_index ); -void init_sbusOut(uint32_t module_index); -void disable_sbusOut(uint32_t module_index); // Trainer driver #define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE) diff --git a/radio/src/targets/taranis/extmodule_driver.cpp b/radio/src/targets/taranis/extmodule_driver.cpp index 95b6878c4fa..c18b86e12f7 100644 --- a/radio/src/targets/taranis/extmodule_driver.cpp +++ b/radio/src/targets/taranis/extmodule_driver.cpp @@ -105,8 +105,42 @@ void extmodulePpmStart() NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); } +void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us) +{ + EXTERNAL_MODULE_ON(); + + GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TIMER_TX_GPIO_AF); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(EXTMODULE_TX_GPIO, &GPIO_InitStructure); + + EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; + EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz + EXTMODULE_TIMER->ARR = period_half_us; + EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | EXTMODULE_TIMER_OUTPUT_POLARITY; + EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs + EXTMODULE_TIMER->CCR1 = 0; + EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high + EXTMODULE_TIMER->EGR = 1; // Restart + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update + EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; + EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; + + extmoduleSendNextFrame(); + + NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); + NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); +} + #if defined(EXTMODULE_USART) -void extmodulePxxStart() +void extmoduleInvertedSerialStart(uint32_t baudrate, uint32_t period_half_us) { EXTERNAL_MODULE_ON(); @@ -138,7 +172,7 @@ void extmodulePxxStart() // UART config USART_DeInit(EXTMODULE_USART); USART_InitTypeDef USART_InitStructure; - USART_InitStructure.USART_BaudRate = EXTMODULE_USART_PXX_BAUDRATE; + USART_InitStructure.USART_BaudRate = baudrate; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_WordLength = USART_WordLength_8b; @@ -150,8 +184,8 @@ void extmodulePxxStart() // Timer EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = 2000 * MODULES_TIMER_PXX_PERIOD; - EXTMODULE_TIMER->CCR2 = (2000 * MODULES_TIMER_PXX_PERIOD) - 2000; // Update time + EXTMODULE_TIMER->ARR = period_half_us; + EXTMODULE_TIMER->CCR2 = period_half_us - 2000; // Update time EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt @@ -160,6 +194,11 @@ void extmodulePxxStart() NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); } + +void extmodulePxxStart() +{ + extmoduleInvertedSerialStart(EXTMODULE_USART_PXX_BAUDRATE, PXX_PERIOD_HALF_US); +} #else void extmodulePxxStart() { @@ -177,7 +216,7 @@ void extmodulePxxStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = 18000; + EXTMODULE_TIMER->ARR = PXX_PERIOD_HALF_US; EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | EXTMODULE_TIMER_OUTPUT_POLARITY; // polarity, default low EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 18; @@ -196,42 +235,6 @@ void extmodulePxxStart() } #endif -#if defined(DSM2) || defined(MULTIMODULE) -void extmoduleDsm2Start() -{ - EXTERNAL_MODULE_ON(); - - GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TIMER_TX_GPIO_AF); - - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(EXTMODULE_TX_GPIO, &GPIO_InitStructure); - - EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; - EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = 44000; // 22mS - EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | EXTMODULE_TIMER_OUTPUT_POLARITY; - EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs - EXTMODULE_TIMER->CCR1 = 0; - EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high - EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update - EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - - extmoduleSendNextFrame(); - - NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); - NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); -} -#endif - void extmoduleCrossfireStart() { EXTERNAL_MODULE_ON(); @@ -249,8 +252,8 @@ void extmoduleCrossfireStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_FRAME_PERIOD); - EXTMODULE_TIMER->CCR2 = (2000 * CROSSFIRE_FRAME_PERIOD) - 1000; + EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_PERIOD); + EXTMODULE_TIMER->CCR2 = (2000 * CROSSFIRE_PERIOD) - 1000; EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt @@ -308,7 +311,7 @@ void extmoduleSendNextFrame() } else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) - EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1NP : 0); // reverse polarity for Sbus if needed + EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // reverse polarity for Sbus if needed EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; diff --git a/radio/src/targets/taranis/pulses_driver.cpp b/radio/src/targets/taranis/pulses_driver.cpp index b8d7690a830..f70a241ed4d 100644 --- a/radio/src/targets/taranis/pulses_driver.cpp +++ b/radio/src/targets/taranis/pulses_driver.cpp @@ -32,9 +32,7 @@ void intmodulePpmStart(void); void extmoduleNoneStart(void); void extmodulePpmStart(void); void extmodulePxxStart(void); -#if defined(DSM2) || defined(MULTIMODULE) -void extmoduleDsm2Start(void); -#endif +void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us); void extmoduleCrossfireStart(void); void init_pxx(uint32_t port) @@ -54,14 +52,14 @@ void disable_pxx(uint32_t port) } #if defined(DSM2) -void init_dsm2(uint32_t port) +void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us) { if (port == EXTERNAL_MODULE) { - extmoduleDsm2Start(); + extmoduleSerialStart(baudrate, period_half_us); } } -void disable_dsm2(uint32_t port) +void disable_serial(uint32_t port) { if (port == EXTERNAL_MODULE) { extmoduleStop(); @@ -69,17 +67,6 @@ void disable_dsm2(uint32_t port) } #endif -void init_sbusOut(uint32_t port) -{ - init_dsm2(port); -} - -void disable_sbusOut(uint32_t port) -{ - disable_dsm2(port); -} - - void init_ppm(uint32_t port) { if (port == EXTERNAL_MODULE) { diff --git a/radio/src/tasks_arm.cpp b/radio/src/tasks_arm.cpp index 4e3af0ed004..9ba6d6df40b 100644 --- a/radio/src/tasks_arm.cpp +++ b/radio/src/tasks_arm.cpp @@ -192,11 +192,11 @@ void mixerTask(void * pdata) } } -void scheduleNextMixerCalculation(uint8_t module, uint16_t delay) +void scheduleNextMixerCalculation(uint8_t module, uint16_t period_ms) { // Schedule next mixer calculation time, // for now assume mixer calculation takes 2 ms. - nextMixerTime[module] = (uint32_t)CoGetOSTime() + (delay)/2 - 1/*2ms*/; + nextMixerTime[module] = (uint32_t)CoGetOSTime() + period_ms / 2 - 1/*2ms*/; DEBUG_TIMER_STOP(debugTimerMixerCalcToUsage); } diff --git a/radio/src/telemetry/crossfire.h b/radio/src/telemetry/crossfire.h index 321da7599af..b80ebdf3650 100644 --- a/radio/src/telemetry/crossfire.h +++ b/radio/src/telemetry/crossfire.h @@ -82,15 +82,15 @@ const uint32_t CROSSFIRE_BAUDRATES[] = { 400000, 115200, }; -const uint8_t CROSSFIRE_FRAME_PERIODS[] = { +const uint8_t CROSSFIRE_PERIODS[] = { 4, 16, }; #define CROSSFIRE_BAUDRATE CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate] -#define CROSSFIRE_FRAME_PERIOD CROSSFIRE_FRAME_PERIODS[g_eeGeneral.telemetryBaudrate] +#define CROSSFIRE_PERIOD CROSSFIRE_PERIODS[g_eeGeneral.telemetryBaudrate] #else #define CROSSFIRE_BAUDRATE 400000 -#define CROSSFIRE_FRAME_PERIOD 4 // 4ms +#define CROSSFIRE_PERIOD 4 // 4ms #endif diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py index 4b3abe1b242..477fde2fda9 100755 --- a/radio/util/build-firmware.py +++ b/radio/util/build-firmware.py @@ -106,6 +106,12 @@ maxsize = 65536 * 8 board = BOARD_TARANIS board_family = BOARD_FAMILY_ARM +elif options[optcount] == "xlite": + command_options["PCB"] = "XLITE" + firmware_options = options_taranisplus + maxsize = 65536 * 8 + board = BOARD_TARANIS + board_family = BOARD_FAMILY_ARM elif options[optcount] == "x9d": command_options["PCB"] = "X9D" firmware_options = options_taranis