Multiprotocol working on sky9x and co (#4409)

* MULTI working on sky9x

* Fix crash with module OFF

* Cosmetics

* Compilation fix / cosmetics

* Typo....

* Multi now available on all ARM platforms

* Does this help?

* Compilation fix
This commit is contained in:
Andre Bernet
2017-02-15 17:31:38 +01:00
committed by GitHub
parent e8b04cdee6
commit fe49fb5442
15 changed files with 145 additions and 50 deletions
@@ -1131,9 +1131,16 @@ void addOpenTxCommonOptions(OpenTxFirmware * firmware)
firmware->addOptions(fai_options);
}
void addOpenTxArmOptions(OpenTxFirmware * firmware)
{
firmware->addOption("multimodule", QObject::tr("Support for the DIY-Multiprotocol-TX-Module"));
firmware->addOption("eu", QObject::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015"));
}
void addOpenTxFrskyOptions(OpenTxFirmware * firmware)
{
addOpenTxCommonOptions(firmware);
addOpenTxArmOptions(firmware);
firmware->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
firmware->addOption("nogvars", QObject::tr("Disable Global variables"));
firmware->addOption("lua", QObject::tr("Support for Lua model scripts"));
@@ -1142,8 +1149,6 @@ void addOpenTxFrskyOptions(OpenTxFirmware * firmware)
{"cli", QObject::tr("Instead of Joystick emulation, USB connection is Command Line Interface")},
{NULL}};
firmware->addOptions(usb_options);
firmware->addOption("eu", QObject::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015"));
firmware->addOption("multimodule", QObject::tr("Support for the DIY-Multiprotocol-TX-Module"));
}
void addOpenTxTaranisOptions(OpenTxFirmware * firmware)
+6
View File
@@ -296,6 +296,12 @@ enum BeeperMode {
};
#endif
#if defined(PCBTARANIS) || defined(PCBHORUS)
#define IS_INTERNAL_MODULE_ENABLED() (g_model.moduleData[INTERNAL_MODULE].rfProtocol != RF_PROTO_OFF)
#elif defined(PCBSKY9X)
#define IS_INTERNAL_MODULE_ENABLED() (false)
#endif
enum UartModes {
#if defined(CLI) || defined(DEBUG)
UART_MODE_DEBUG,
+1 -1
View File
@@ -204,7 +204,7 @@ void menuRadioHardware(event_t event)
case ITEM_RADIO_HARDWARE_UART3_MODE:
g_eeGeneral.serial2Mode = editChoice(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.serial2Mode, 0, UART_MODE_MAX, attr, event);
if (attr && checkIncDec_Ret) {
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
serial2Init(g_eeGeneral.serial2Mode, modelTelemetryProtocol());
}
break;
case ITEM_RADIO_HARDWARE_JITTER_FILTER:
+1 -1
View File
@@ -181,7 +181,7 @@ bool menuRadioHardware(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_UART3MODE);
g_eeGeneral.serial2Mode = editChoice(HW_SETTINGS_COLUMN+50, y, STR_UART3MODES, g_eeGeneral.serial2Mode, 0, UART_MODE_MAX, attr, event);
if (attr && checkIncDec_Ret) {
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
serial2Init(g_eeGeneral.serial2Mode, modelTelemetryProtocol());
}
break;
#endif
+1 -1
View File
@@ -2492,7 +2492,7 @@ void opentxInit(OPENTX_INIT_ARGS)
#endif // #if !defined(EEPROM)
#if defined(SERIAL2)
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
serial2Init(g_eeGeneral.serial2Mode, modelTelemetryProtocol());
#endif
#if defined(PCBTARANIS)
+1 -1
View File
@@ -46,7 +46,7 @@ static void sendByteMulti(uint8_t b)
parity = parity ^ (b & 1);
b >>= 1;
}
putDsm2SerialBit(parity); // Even Parity bit
putDsm2SerialBit(!parity); // Even Parity bit
putDsm2SerialBit(1); // Stop bit
putDsm2SerialBit(1); // Stop bit
+5 -2
View File
@@ -146,7 +146,7 @@ void setupPulses(uint8_t port)
#if defined(MULTIMODULE)
case PROTO_MULTIMODULE:
disable_dsm2(port);
disable_multimodule(port);
break;
#endif
@@ -208,6 +208,9 @@ void setupPulses(uint8_t port)
#endif
case PROTO_PPM:
#if defined(PCBSKY9X)
case PROTO_NONE:
#endif
setupPulsesPPMModule(port);
scheduleNextMixerCalculation(port, (45+g_model.moduleData[port].ppm.frameLength)/2);
break;
@@ -238,7 +241,7 @@ void setupPulses(uint8_t port)
#if defined(MULTIMODULE)
case PROTO_MULTIMODULE:
init_dsm2(port);
init_multimodule(port);
break;
#endif
+5
View File
@@ -193,6 +193,11 @@ void disable_dsm2(uint32_t module_index);
void init_crossfire(uint32_t module_index);
void disable_crossfire(uint32_t module_index);
#if defined(MULTIMODULE)
void init_multimodule(uint32_t module_index);
void disable_multimodule(uint32_t module_index);
#endif
// Trainer driver
void init_trainer_ppm(void);
void stop_trainer_ppm(void);
+12
View File
@@ -96,6 +96,18 @@ void disable_dsm2(uint32_t port)
}
#endif
#if defined(MULTIMODULE)
void init_multimodule(uint32_t port)
{
init_dsm2(port);
}
void disable_multimodule(uint32_t port)
{
disable_dsm2(port);
}
#endif
void init_crossfire(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
+5
View File
@@ -260,6 +260,11 @@ void disable_pxx(uint32_t port);
void init_dsm2(uint32_t port);
void disable_dsm2(uint32_t port);
#if defined(MULTIMODULE)
void init_multimodule(uint32_t module_index);
void disable_multimodule(uint32_t module_index);
#endif
// SD driver
#if defined(SIMU)
#define sdInit()
+74 -32
View File
@@ -25,9 +25,9 @@ void setExternalModulePolarity()
Pwm * pwmptr = PWM;
pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = GET_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS
if (GET_PPM_POLARITY(EXTERNAL_MODULE))
pwmptr->PWM_CH_NUM[3].PWM_CMR &= ~0x00000200; // CPOL
pwmptr->PWM_CH_NUM[3].PWM_CMR &= ~0x00000200; // CPOL
else
pwmptr->PWM_CH_NUM[3].PWM_CMR |= 0x00000200; // CPOL
pwmptr->PWM_CH_NUM[3].PWM_CMR |= 0x00000200; // CPOL
}
void setExtraModulePolarity()
@@ -35,9 +35,9 @@ void setExtraModulePolarity()
Pwm * pwmptr = PWM;
pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE) * 2; // Duty in half uS
if (GET_PPM_POLARITY(EXTRA_MODULE))
pwmptr->PWM_CH_NUM[1].PWM_CMR &= ~0x00000200; // CPOL
pwmptr->PWM_CH_NUM[1].PWM_CMR &= ~0x00000200; // CPOL
else
pwmptr->PWM_CH_NUM[1].PWM_CMR |= 0x00000200; // CPOL
pwmptr->PWM_CH_NUM[1].PWM_CMR |= 0x00000200; // CPOL
}
void module_output_active()
@@ -54,7 +54,7 @@ void module_output_active()
pioptr->PIO_MDER = PIO_PA17; // Open Drain O/p in A17
}
#else
pioptr->PIO_MDDR = PIO_PA17; // Push Pull O/p in A17
pioptr->PIO_MDDR = PIO_PA17; // Push Pull O/p in A17
#endif
pioptr->PIO_PUER = PIO_PA17; // With pull up
}
@@ -71,23 +71,23 @@ void init_main_ppm(uint32_t period, uint32_t out_enable)
pwmptr = PWM;
// PWM3 for PPM output
pwmptr->PWM_CH_NUM[3].PWM_CMR = 0x0004000B; // CLKA
pwmptr->PWM_CH_NUM[3].PWM_CPDR = period; // Period in half uS
pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = period; // Period in half uS
pwmptr->PWM_CH_NUM[3].PWM_CMR = 0x0004000B; // CLKA
pwmptr->PWM_CH_NUM[3].PWM_CPDR = period; // Period in half uS
pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = period; // Period in half uS
pwmptr->PWM_CH_NUM[3].PWM_CDTY = GET_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS
pwmptr->PWM_ENA = PWM_ENA_CHID3; // Enable channel 3
pwmptr->PWM_ENA = PWM_ENA_CHID3; // Enable channel 3
pwmptr->PWM_IER1 = PWM_IER1_CHID3;
setExternalModulePolarity();
NVIC_SetPriority(PWM_IRQn, 3 );
NVIC_SetPriority(PWM_IRQn, 3);
NVIC_EnableIRQ(PWM_IRQn);
}
void disable_main_ppm()
{
Pio * pioptr = PIOA;
pioptr->PIO_PER = PIO_PA17; // Assign A17 to PIO
pioptr->PIO_PER = PIO_PA17; // Assign A17 to PIO
PWM->PWM_IDR1 = PWM_IDR1_CHID3;
}
@@ -96,16 +96,16 @@ void init_second_ppm(uint32_t period)
#if !defined(REVA)
// PWM1 for PPM2
Pwm * pwmptr = PWM;
configure_pins(PIO_PC15, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_NO_PULLUP );
pwmptr->PWM_CH_NUM[1].PWM_CMR = 0x0000000B; // CLKB
configure_pins(PIO_PC15, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_NO_PULLUP);
pwmptr->PWM_CH_NUM[1].PWM_CMR = 0x0000000B; // CLKB
if (!GET_PPM_POLARITY(EXTRA_MODULE)) {
pwmptr->PWM_CH_NUM[1].PWM_CMR |= 0x00000200; // CPOL
pwmptr->PWM_CH_NUM[1].PWM_CMR |= 0x00000200; // CPOL
}
pwmptr->PWM_CH_NUM[1].PWM_CPDR = period; // Period
pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = period; // Period
pwmptr->PWM_CH_NUM[1].PWM_CDTY = GET_PPM_DELAY(EXTRA_MODULE)*2; // Duty
pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE)*2; // Duty
pwmptr->PWM_ENA = PWM_ENA_CHID1; // Enable channel 1
pwmptr->PWM_CH_NUM[1].PWM_CPDR = period; // Period
pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = period; // Period
pwmptr->PWM_CH_NUM[1].PWM_CDTY = GET_PPM_DELAY(EXTRA_MODULE)*2; // Duty
pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE)*2; // Duty
pwmptr->PWM_ENA = PWM_ENA_CHID1; // Enable channel 1
pwmptr->PWM_IER1 = PWM_IER1_CHID1;
#endif
}
@@ -114,7 +114,7 @@ void disable_second_ppm()
{
#if !defined(REVA)
Pio * pioptr = PIOC;
pioptr->PIO_PER = PIO_PC15; // Assign C17 to PIO
pioptr->PIO_PER = PIO_PC15; // Assign C17 to PIO
PWM->PWM_IDR1 = PWM_IDR1_CHID1;
#endif
}
@@ -161,19 +161,19 @@ void disable_ppm(uint32_t port)
// Initialise the SSC to allow PXX output.
// TD is on PA17, peripheral A
void init_ssc()
void init_ssc(uint8_t baudrateDiv1000)
{
Ssc * sscptr;
PMC->PMC_PCER0 |= 0x00400000L; // Enable peripheral clock to SSC
PMC->PMC_PCER0 |= 0x00400000L; // Enable peripheral clock to SSC
configure_pins(PIO_PA17, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTA);
sscptr = SSC;
sscptr->SSC_THR = 0xFF; // Make the output high.
sscptr->SSC_TFMR = 0x00000027; // 0000 0000 0000 0000 0000 0000 1010 0111 (8 bit data, lsb)
sscptr->SSC_CMR = Master_frequency / (125000*2); // 8uS per bit
sscptr->SSC_TCMR = 0; // 0000 0000 0000 0000 0000 0000 0000 0000
sscptr->SSC_THR = 0xFF; // Make the output high.
sscptr->SSC_TFMR = 0x00000027; // 0000 0000 0000 0000 0000 0000 1010 0111 (8 bit data, lsb)
sscptr->SSC_CMR = Master_frequency / (1000*baudrateDiv1000*2);
sscptr->SSC_TCMR = 0;
sscptr->SSC_CR = SSC_CR_TXEN;
#if defined(REVX)
@@ -190,7 +190,7 @@ void disable_ssc()
// Revert back to pwm output
pioptr = PIOA;
pioptr->PIO_PER = PIO_PA17; // Assign A17 to PIO
pioptr->PIO_PER = PIO_PA17; // Assign A17 to PIO
sscptr = SSC;
sscptr->SSC_CR = SSC_CR_TXDIS;
@@ -200,7 +200,7 @@ void init_pxx(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
init_main_ppm(2500 * 2, 0);
init_ssc();
init_ssc(125); // 8us per bit
}
else {
// TODO
@@ -222,8 +222,8 @@ void init_dsm2(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
init_main_ppm(2500 * 2, 0);
init_ssc();
}
init_ssc(125);
}
else {
// TODO
}
@@ -240,6 +240,24 @@ void disable_dsm2(uint32_t port)
}
}
#if defined(MULTIMODULE)
void init_multimodule(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
init_main_ppm(3500 * 2, 0);
init_ssc(100);
}
else {
// TODO
}
}
void disable_multimodule(uint32_t port)
{
disable_dsm2(port);
}
#endif
#if !defined(SIMU)
extern "C" void PWM_IRQHandler(void)
{
@@ -269,7 +287,7 @@ extern "C" void PWM_IRQHandler(void)
Ssc * sscptr = SSC;
sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.pulses);
sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].pxx.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].pxx.pulses;
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
}
break;
@@ -293,10 +311,34 @@ extern "C" void PWM_IRQHandler(void)
Ssc * sscptr = SSC;
sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses);
sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
}
break;
#if defined(MULTIMODULE)
case PROTO_MULTIMODULE:
// Alternate periods of 5.5mS and 3.5 mS
period = pwmptr->PWM_CH_NUM[3].PWM_CPDR;
if (period == 3500 * 2) {
period = 5500 * 2;
}
else {
period = 3500 * 2;
}
pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = period; // Period in half uS
if (period != 3500 * 2) {
setupPulses(EXTERNAL_MODULE);
}
else {
// Kick off serial output here
Ssc * sscptr = SSC;
sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses);
sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
}
break;
#endif
default:
pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++;
if (*modulePulsesData[EXTERNAL_MODULE].ppm.ptr == 0) {
+5
View File
@@ -190,6 +190,11 @@ void disable_dsm2( uint32_t module_index );
void init_crossfire( uint32_t module_index );
void disable_crossfire( uint32_t module_index );
#if defined(MULTIMODULE)
void init_multimodule(uint32_t module_index);
void disable_multimodule(uint32_t module_index);
#endif
// Trainer driver
void init_trainer_ppm(void);
void stop_trainer_ppm(void);
+14 -1
View File
@@ -55,7 +55,7 @@ void disable_pxx(uint32_t port)
extmoduleStop();
}
#if defined(DSM2) || defined(MULTIMODULE)
#if defined(DSM2)
void init_dsm2(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
@@ -71,6 +71,19 @@ void disable_dsm2(uint32_t port)
}
#endif
#if defined(MULTIMODULE)
void init_multimodule(uint32_t port)
{
init_dsm2(port);
}
void disable_multimodule(uint32_t port)
{
disable_dsm2(port);
}
#endif
void init_ppm(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
+5 -3
View File
@@ -74,10 +74,12 @@ void processTelemetryData(uint8_t data)
if (telemetryProtocol == PROTOCOL_SPEKTRUM) {
processSpektrumTelemetryData(data);
return;
} else if (telemetryProtocol == PROTOCOL_FLYSKY_IBUS) {
}
if (telemetryProtocol == PROTOCOL_FLYSKY_IBUS) {
processFlySkyTelemetryData(data);
return;
} else if (telemetryProtocol == PROTOCOL_MULTIMODULE) {
}
if (telemetryProtocol == PROTOCOL_MULTIMODULE) {
processMultiTelemetryData(data);
return;
}
@@ -88,7 +90,7 @@ void processTelemetryData(uint8_t data)
void telemetryWakeup()
{
#if defined(CPUARM)
uint8_t requiredTelemetryProtocol = MODEL_TELEMETRY_PROTOCOL();
uint8_t requiredTelemetryProtocol = modelTelemetryProtocol();
#if defined(REVX)
uint8_t requiredSerialInversion = g_model.moduleData[EXTERNAL_MODULE].invertedSerial;
if (telemetryProtocol != requiredTelemetryProtocol || serialInversion != requiredSerialInversion) {
+3 -6
View File
@@ -139,7 +139,7 @@ extern uint8_t telemetryProtocol;
#define IS_FRSKY_SPORT_PROTOCOL() (false)
#endif
#if defined(PCBTARANIS) || defined(PCBHORUS)
#if defined(CPUARM)
inline uint8_t modelTelemetryProtocol()
{
#if defined(CROSSFIRE)
@@ -148,12 +148,12 @@ inline uint8_t modelTelemetryProtocol()
}
#endif
if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) {
if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) {
return g_model.telemetryProtocol;
}
#if defined(MULTIMODULE)
if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) {
if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) {
return PROTOCOL_MULTIMODULE;
}
#endif
@@ -161,9 +161,6 @@ inline uint8_t modelTelemetryProtocol()
// default choice
return PROTOCOL_FRSKY_SPORT;
}
#define MODEL_TELEMETRY_PROTOCOL() modelTelemetryProtocol()
#elif defined(CPUARM)
#define MODEL_TELEMETRY_PROTOCOL() g_model.telemetryProtocol
#endif
#if defined(CPUARM)