diff --git a/src/eeprom_conversions.cpp b/src/eeprom_conversions.cpp index 3e3e23004..9567882e6 100644 --- a/src/eeprom_conversions.cpp +++ b/src/eeprom_conversions.cpp @@ -122,6 +122,8 @@ PACK(typedef struct { bool eeConvert() { + return false; + if (g_eeGeneral.version == 212) { g_eeGeneral.optrexDisplay = 0; g_eeGeneral.backlightBright = 0; @@ -167,10 +169,10 @@ bool eeConvert() g_model.ppmNCH = oldModel.ppmNCH; g_model.trimInc = oldModel.trimInc; g_model.disableThrottleWarning = oldModel.disableThrottleWarning; - g_model.pulsePol = oldModel.pulsePol; + g_model.moduleData[0].ppmPulsePol = oldModel.pulsePol; g_model.extendedLimits = oldModel.extendedLimits; g_model.extendedTrims = oldModel.extendedTrims; - g_model.ppmDelay = oldModel.ppmDelay; + g_model.moduleData[0].ppmDelay = oldModel.ppmDelay; g_model.beepANACenter = oldModel.beepANACenter; for (uint8_t i=0; i<64; i++) { g_model.mixData[i].destCh = oldModel.mixData[i].destCh; @@ -218,7 +220,7 @@ bool eeConvert() memcpy(g_model.phaseData[i].trim, oldModel.phaseData[i].trim, 4*sizeof(int16_t)); memcpy(g_model.phaseData[i].rotaryEncoders, oldModel.phaseData[i].rotaryEncoders, 1*sizeof(int16_t)); } - g_model.ppmFrameLength = oldModel.ppmFrameLength; + g_model.moduleData[0].ppmFrameLength = oldModel.ppmFrameLength; g_model.thrTraceSrc = oldModel.thrTraceSrc; g_model.header.modelId = oldModel.modelId; g_model.switchWarningStates = oldModel.switchWarningStates; diff --git a/src/menu_model.cpp b/src/menu_model.cpp index e3cfbdb5a..1b95a39fa 100644 --- a/src/menu_model.cpp +++ b/src/menu_model.cpp @@ -675,7 +675,7 @@ void menuModelFailsafe(uint8_t event) eeDirty(EE_MODEL); s_editMode = 0; AUDIO_WARNING1(); - SEND_FAILSAFE_NOW(); + SEND_FAILSAFE_NOW(g_moduleIdx); killEvents(event); } @@ -903,8 +903,8 @@ void menuModelSetup(uint8_t event) #if defined(PCBTARANIS) if (event == EVT_KEY_LONG(KEY_EXIT)) { - pxxFlag[0] = 0; - pxxFlag[1] = 0; + pxxFlag[INTERNAL_MODULE] = 0; + pxxFlag[EXTERNAL_MODULE] = 0; } #endif @@ -1161,13 +1161,14 @@ void menuModelSetup(uint8_t event) if (checkIncDec_Ret) { g_model.moduleData[0].channelsStart = 0; g_model.moduleData[0].channelsCount = MAX_PORT1_CHANNELS(); + setupPulses(INTERNAL_MODULE); } } break; case ITEM_MODEL_EXTERNAL_MODULE_MODE: lcd_putsLeft(y, PSTR(INDENT "Module")); - lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""---\0""PPM\0""XJT\0""DJT\0""DSM2"), g_model.externalModule, m_posHorz==0 ? attr : 0); + lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""PPM\0""XJT\0""DJT\0""DSM2"), g_model.externalModule, m_posHorz==0 ? attr : 0); if (g_model.externalModule == MODULE_TYPE_XJT) lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+5*FW, y, PSTR("\004""OFF\0""X16\0""D8\0 ""LR12"), 1+g_model.moduleData[1].rfProtocol, m_posHorz==1 ? attr : 0); if (attr && (editMode>0 || p1valdiff)) { @@ -1176,7 +1177,11 @@ void menuModelSetup(uint8_t event) CHECK_INCDEC_MODELVAR(event, g_model.externalModule, MODULE_TYPE_NONE, MODULE_TYPE_LAST); if (checkIncDec_Ret) { g_model.moduleData[1].channelsStart = 0; - g_model.moduleData[1].channelsCount = MAX_PORT2_CHANNELS(); + if (g_model.externalModule == MODULE_TYPE_PPM) + g_model.moduleData[1].channelsCount = 0; + else + g_model.moduleData[1].channelsCount = MAX_PORT2_CHANNELS(); + setupPulses(EXTERNAL_MODULE); } break; case 1: @@ -1208,7 +1213,9 @@ void menuModelSetup(uint8_t event) CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); break; case 1: - CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsCount, min(MAX_CHANNELS(moduleIdx), 32-moduleData.channelsStart-8)); + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsCount, min(MAX_CHANNELS(moduleIdx), 32-8-moduleData.channelsStart)); + if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.externalModule == MODULE_TYPE_PPM) || (k == ITEM_MODEL_TRAINER_CHANNELS)) + moduleData.ppmFrameLength = moduleData.channelsCount * 4; break; } } @@ -1291,7 +1298,7 @@ void menuModelSetup(uint8_t event) if (m_posHorz==0) { if (editMode>0 || p1valdiff) { CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.failsafeMode, FAILSAFE_LAST); - if (checkIncDec_Ret) SEND_FAILSAFE_NOW(); + if (checkIncDec_Ret) SEND_FAILSAFE_NOW(moduleIdx); } } else if (m_posHorz==1) { @@ -1314,7 +1321,7 @@ void menuModelSetup(uint8_t event) break; case ITEM_MODEL_TRAINER_MODE: - g_model.trainerMode = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_MODE, PSTR("\006MasterSlave"), g_model.trainerMode, 0, 1, attr, event); break; + g_model.trainerMode = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_MODE, PSTR("\006MasterSlave"), g_model.trainerMode, 0, 1, attr, event); break; #else @@ -1330,9 +1337,9 @@ void menuModelSetup(uint8_t event) #if defined(PCBSKY9X) lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+4*FW+3, y, STR_CH, m_posHorz==1 ? attr : 0); - lcd_outdezAtt(lcdLastPos, y, g_model.ppmSCH+1, LEFT | (m_posHorz==1 ? attr : 0)); + lcd_outdezAtt(lcdLastPos, y, g_model.moduleData[0].channelsStart+1, LEFT | (m_posHorz==1 ? attr : 0)); lcd_putc(lcdLastPos, y, '-'); - lcd_outdezAtt(lcdLastPos + FW+1, y, g_model.ppmSCH+NUM_PORT1_CHANNELS(), LEFT | (m_posHorz==2 ? attr : 0)); + lcd_outdezAtt(lcdLastPos + FW+1, y, g_model.moduleData[0].channelsStart+NUM_PORT1_CHANNELS(), LEFT | (m_posHorz==2 ? attr : 0)); #else if (IS_PPM_PROTOCOL(protocol)) { lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+7*FW, y, STR_NCHANNELS, g_model.ppmNCH+2, m_posHorz!=0 ? attr : 0); @@ -1353,8 +1360,8 @@ void menuModelSetup(uint8_t event) break; case 1: #if defined(PCBSKY9X) - CHECK_INCDEC_MODELVAR_ZERO(event, g_model.ppmSCH, 32-8-(g_model.ppmNCH*2)); - g_model.ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[0].channelsStart, 32-8-g_model.moduleData[0].channelsCount); + g_model.moduleData[0].ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); #else CHECK_INCDEC_MODELVAR(event, g_model.ppmNCH, -2, 4); g_model.ppmFrameLength = g_model.ppmNCH * 8; @@ -1363,8 +1370,8 @@ void menuModelSetup(uint8_t event) #if defined(PCBSKY9X) case 2: if (IS_PPM_PROTOCOL(protocol)) { - CHECK_INCDEC_MODELVAR(event, g_model.ppmNCH, -2, min(4, (32-g_model.ppmSCH)/2-4)); - g_model.ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[0].channelsCount, -4, min(8, 32-8-g_model.moduleData[0].channelsStart)); + g_model.moduleData[0].ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); } else REPEAT_LAST_CURSOR_MOVE(); @@ -1386,17 +1393,41 @@ void menuModelSetup(uint8_t event) switch (m_posHorz) { case 0: CHECK_INCDEC_MODELVAR_ZERO(event, g_model.ppm2SCH, 32-8-(g_model.ppm2NCH*2)); - g_model.ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); + g_model.moduleData[1].ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); break; case 1: CHECK_INCDEC_MODELVAR(event, g_model.ppm2NCH, -2, min(4, (32-g_model.ppm2SCH)/2-4)); - g_model.ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); + g_model.moduleData[1].ppmFrameLength = NUM_PORT1_CHANNELS()>NUM_PORT2_CHANNELS() ? 4*(NUM_PORT1_CHANNELS()-8) : 4*(NUM_PORT2_CHANNELS()-8); break; } } break; #endif +#if defined(PCBSKY9X) + case ITEM_MODEL_PROTOCOL_PARAMS: + if (IS_PPM_PROTOCOL(protocol)) { + lcd_putsLeft(y, STR_PPMFRAME); + lcd_puts(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS); + lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN, y, (int16_t)g_model.moduleData[0].ppmFrameLength*5 + 225, (m_posHorz<=0 ? attr : 0) | PREC1|LEFT); + lcd_putc(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); + lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (g_model.moduleData[0].ppmDelay*50)+300, (m_posHorz < 0 || m_posHorz==1) ? attr : 0); + lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+10*FW, y, g_model.moduleData[0].ppmPulsePol ? '+' : '-', (m_posHorz < 0 || m_posHorz==2) ? attr : 0); + if (attr && (editMode>0 || p1valdiff)) { + switch (m_posHorz) { + case 0: + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[0].ppmFrameLength, -20, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[0].ppmDelay, -4, 10); + break; + case 2: + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[0].ppmPulsePol, 1); + break; + } + } + } +#else case ITEM_MODEL_PROTOCOL_PARAMS: if (IS_PPM_PROTOCOL(protocol)) { lcd_putsLeft(y, STR_PPMFRAME); @@ -1405,7 +1436,6 @@ void menuModelSetup(uint8_t event) lcd_putc(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (g_model.ppmDelay*50)+300, (m_posHorz < 0 || m_posHorz==1) ? attr : 0); lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+10*FW, y, g_model.pulsePol ? '+' : '-', (m_posHorz < 0 || m_posHorz==2) ? attr : 0); - if (attr && (editMode>0 || p1valdiff)) { switch (m_posHorz) { case 0: @@ -1420,6 +1450,7 @@ void menuModelSetup(uint8_t event) } } } +#endif #if defined(DSM2) || defined(PXX) else if (IS_DSM2_PROTOCOL(protocol) || IS_PXX_PROTOCOL(protocol)) { if (attr && m_posHorz > 1) { @@ -1468,7 +1499,7 @@ void menuModelSetup(uint8_t event) } #if defined(PCBTARANIS) - if (pxxFlag[0] == PXX_SEND_RANGECHECK || pxxFlag[1] == PXX_SEND_RANGECHECK) { + if (pxxFlag[INTERNAL_MODULE] == PXX_SEND_RANGECHECK || pxxFlag[EXTERNAL_MODULE] == PXX_SEND_RANGECHECK) { displayPopup("RSSI: "); lcd_outdezAtt(16+4*FW, 5*FH, frskyData.rssi[0].value, BOLD); } @@ -2219,11 +2250,13 @@ void menuModelCurveOne(uint8_t event) pointsOfs = 0; break; case EVT_KEY_LONG(KEY_ENTER): - killEvents(event); - MENU_ADD_ITEM(STR_CURVE_PRESET); - MENU_ADD_ITEM(STR_CURVE_MIRROR); - MENU_ADD_ITEM(STR_CURVE_CLEAR); - menuHandler = onCurveOneMenu; + if (m_posVert > 1) { + killEvents(event); + MENU_ADD_ITEM(STR_CURVE_PRESET); + MENU_ADD_ITEM(STR_CURVE_MIRROR); + MENU_ADD_ITEM(STR_CURVE_CLEAR); + menuHandler = onCurveOneMenu; + } break; } diff --git a/src/myeeprom.h b/src/myeeprom.h index 60951b5a1..0845c4124 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -123,7 +123,7 @@ #define CURVTYPE int8_t #endif -#if defined(PCBTARANIS) +#if defined(PCBTARANIS) || defined(PCBSKY9X) #define NUM_MODULES 2 #else #define NUM_MODULES 1 @@ -228,6 +228,11 @@ PACK(typedef struct t_ModuleData { }) ModuleData; #if defined(PCBTARANIS) +enum ModuleIndex { + INTERNAL_MODULE, + EXTERNAL_MODULE, + TRAINER_MODULE +}; #define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME]; #define MODELDATA_EXTRA uint8_t externalModule; uint8_t trainerMode; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; #define LIMITDATA_EXTRA char name[6]; diff --git a/src/opentx.cpp b/src/opentx.cpp index 649fe8f51..d66e569f2 100644 --- a/src/opentx.cpp +++ b/src/opentx.cpp @@ -300,7 +300,7 @@ void per10ms() sdPoll10ms(); #endif - heartbeat |= HEART_TIMER10ms; + heartbeat |= HEART_TIMER_10MS; } PhaseData *phaseaddress(uint8_t idx) @@ -4160,7 +4160,17 @@ void mixerTask(void * pdata) CoLeaveMutexSection(mixerMutex); if (tick10ms) checkTrims(); - if (heartbeat == HEART_TIMER_PULSES+HEART_TIMER10ms) { + uint8_t heartbeatCheck = HEART_TIMER_10MS; +#if defined(PCBTARANIS) + if (g_model.moduleData[0].rfProtocol != RF_PROTO_OFF) + heartbeatCheck |= HEART_TIMER_PULSES; + if (g_model.externalModule != MODULE_TYPE_NONE) + heartbeatCheck |= HEART_TIMER_PULSES << 1; +#else + uint8_t heartbeatCheck = HEART_TIMER_10MS + HEART_TIMER_PULSES; +#endif + + if ((heartbeat & heartbeatCheck) == heartbeatCheck) { wdt_reset(); heartbeat = 0; } @@ -4355,7 +4365,7 @@ int main(void) perMain(); - if (heartbeat == HEART_TIMER_PULSES+HEART_TIMER10ms) { + if (heartbeat == HEART_TIMER_PULSES+HEART_TIMER_10MS) { wdt_reset(); heartbeat = 0; } diff --git a/src/opentx.h b/src/opentx.h index cc2156788..3e28e93ec 100644 --- a/src/opentx.h +++ b/src/opentx.h @@ -465,9 +465,9 @@ enum EnumKeys { #define MAX_PORT2_CHANNELS() ((g_model.externalModule == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[1].rfProtocol] : maxChannelsModules[g_model.externalModule]) #define MAX_TRAINER_CHANNELS() (8) #define MAX_CHANNELS(idx) (idx==0 ? MAX_PORT1_CHANNELS() : (idx==1 ? MAX_PORT2_CHANNELS() : MAX_TRAINER_CHANNELS())) -#else - #define NUM_PORT1_CHANNELS() (IS_PXX_PROTOCOL(g_model.protocol) ? 8 : (IS_DSM2_PROTOCOL(g_model.protocol) ? 6 : (8+(g_model.ppmNCH*2)))) - #define NUM_PORT2_CHANNELS() (8+(g_model.ppm2NCH*2)) +#elif defined(PCBSKY9X) + #define NUM_PORT1_CHANNELS() (IS_PXX_PROTOCOL(g_model.protocol) ? 8 : (IS_DSM2_PROTOCOL(g_model.protocol) ? 6 : (8+g_model.moduleData[0].channelsCount))) + #define NUM_PORT2_CHANNELS() (8+g_model.moduleData[1].channelsCount) #endif #include "lcd.h" @@ -658,9 +658,8 @@ enum CswFunctions { #define NAVIGATION_RE_IDX() 0 #endif - -#define HEART_TIMER_PULSES 1 -#define HEART_TIMER10ms 2 +#define HEART_TIMER_10MS 1 +#define HEART_TIMER_PULSES 2 // when multiple modules this is the first one extern uint8_t heartbeat; #define MAX_ALERT_TIME 60 diff --git a/src/pulses_arm.cpp b/src/pulses_arm.cpp index 8ac1f432d..302496c4e 100644 --- a/src/pulses_arm.cpp +++ b/src/pulses_arm.cpp @@ -36,29 +36,34 @@ #include "opentx.h" -uint8_t s_pulses_paused = 0; -uint8_t s_current_protocol = 255; -uint32_t failsafeCounter = 100; -uint8_t pxxFlag[NUM_MODULES] = { 0 }; - -uint16_t ppmStream[20] = { 2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400, 9000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; -uint16_t ppm2Stream[20] = { 2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400, 9000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; - -#if defined(PCBSKY9X) -volatile uint32_t ppmStreamIndex = 0 ; // Modified in interrupt routine -volatile uint32_t ppm2StreamIndex = 0 ; // Modified in interrupt routine -uint8_t Bit_pulses[64] ; // Likely more than we need -uint8_t *Pulses2MHzptr ; +#if NUM_MODULES == 2 + #define MODULES_INIT(x) x, x #else -uint16_t pxxStream[400] ; // Transisitions - #if defined(PCBTARANIS) -uint16_t pxx2Stream[400] ; // Transisitions + #define MODULES_INIT(x) x +#endif + +uint8_t s_pulses_paused = 0; +uint8_t s_current_protocol[NUM_MODULES] = { MODULES_INIT(255) }; +uint32_t failsafeCounter[NUM_MODULES] = { MODULES_INIT(100) }; + +uint8_t pxxFlag[NUM_MODULES] = { MODULES_INIT(0) }; +uint16_t pxxStream[NUM_MODULES][400] ; // Transitions uint16_t *pxxStreamPtr[NUM_MODULES] ; uint16_t PxxValue[NUM_MODULES] ; - #else -uint16_t *pxxStreamPtr ; -uint16_t PxxValue ; - #endif +uint16_t PcmCrc[NUM_MODULES] ; +uint8_t PcmOnesCount[NUM_MODULES] ; + +#if NUM_MODULES == 2 +uint16_t ppmStream[NUM_MODULES][20] = { { 2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400, 9000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400, 9000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +#else +uint16_t ppmStream[NUM_MODULES][20] = { { 2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400, 9000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +#endif + +#if defined(PCBSKY9X) +volatile uint32_t ppmStreamIndex[NUM_MODULES] = { MODULES_INIT(0) }; // Modified in interrupt routine +uint8_t Bit_pulses[64] ; // Likely more than we need +uint8_t *Pulses2MHzptr ; #endif // DSM2 control bits @@ -73,38 +78,7 @@ uint8_t Serial_byte ; uint8_t Serial_bit_count; uint8_t Serial_byte_count ; -#if defined(PCBTARANIS) -#define MODULE_INDEX_PARAM uint32_t module_index -#else -#define MODULE_INDEX_PARAM -#endif - -void setupPulses( MODULE_INDEX_PARAM ) ; - -void setupPulsesDsm2(uint8_t chns); -void setupPulsesPXX(); - -void startPulses() -{ - // TODO a single call to setupPulses() should be ok! -#if defined(PCBSKY9X) - init_main_ppm(3000, 1) ; // Default for now, initial period 1.5 mS, output on -#else - #if defined(PCBTARANIS) - init_ppm( 0 ) ; - #else - init_main_ppm(); - #endif -#endif -} - -#if defined(PCBSKY9X) -#define PPM_PORT_PARAM uint32_t ppmPort -#else -#define PPM_PORT_PARAM -#endif - -void setupPulsesPPM(PPM_PORT_PARAM) // Don't enable interrupts through here +void setupPulsesPPM(unsigned int port) // Don't enable interrupts through here { #if defined(PCBSKY9X) register Pwm *pwmptr = PWM; @@ -116,38 +90,30 @@ void setupPulsesPPM(PPM_PORT_PARAM) // Don't enable interrupts // each pulse is 0.7..1.7ms long with a 0.3ms stop tail // The pulse ISR is 2mhz that's why everything is multiplied by 2 + uint32_t firstCh = g_model.moduleData[port].channelsStart; + uint32_t lastCh = min(NUM_CHNOUT, firstCh + 8 + g_model.moduleData[port].channelsCount); + #if defined(PCBSKY9X) uint32_t pwmCh; - uint16_t * ptr; - uint32_t firstCh, lastCh; - if (ppmPort == 0) { + if (port == 0) { pwmCh = 3; - ptr = ppmStream; - firstCh = g_model.ppmSCH; - lastCh = min(NUM_CHNOUT, firstCh + 8 + (g_model.ppmNCH * 2)); } else { pwmCh = 1; - ptr = ppm2Stream; - firstCh = g_model.ppm2SCH; - lastCh = min(NUM_CHNOUT, firstCh + NUM_PORT2_CHANNELS()); } -#else - #define firstCh 0 - uint32_t lastCh = NUM_CHANNELS(0); - uint16_t * ptr = ppmStream; #endif + uint16_t * ptr = ppmStream[port]; #if defined(PCBSKY9X) - pwmptr->PWM_CH_NUM[pwmCh].PWM_CDTYUPD = (g_model.ppmDelay * 50 + 300) * 2; //Stoplen *2 - if (g_model.pulsePol) + pwmptr->PWM_CH_NUM[pwmCh].PWM_CDTYUPD = (g_model.moduleData[port].ppmDelay * 50 + 300) * 2; //Stoplen *2 + if (g_model.moduleData[port].ppmPulsePol) pwmptr->PWM_CH_NUM[pwmCh].PWM_CMR |= 0x00000200 ; // CPOL else pwmptr->PWM_CH_NUM[pwmCh].PWM_CMR &= ~0x00000200 ; // CPOL #endif uint32_t rest = 22500u * 2; //Minimum Framelen=22.5 ms - rest += (int32_t(g_model.ppmFrameLength)) * 1000; + rest += (int32_t(g_model.moduleData[port].ppmFrameLength)) * 1000; for (uint32_t i=firstCh; iCCR2 = rest - 1000 ; // Update time - TIM8->CCR1 = (g_model.ppmDelay*50+300)*2 ; -// TIM1->CCR2 = rest - 1000 ; // Update time -// TIM1->CCR3 = (g_model.ppmDelay*50+300)*2 ; + if (port == EXTERNAL_MODULE) { + TIM8->CCR2 = rest - 1000; // Update time + TIM8->CCR1 = (g_model.moduleData[port].ppmDelay*50+300)*2; + } + else { + TIM1->CCR2 = rest - 1000; // Update time + TIM1->CCR3 = (g_model.moduleData[port].ppmDelay*50+300)*2; + } #endif } @@ -204,276 +171,137 @@ const uint16_t CRCTable[]= 0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78 }; -#if defined(PCBTARANIS) -uint16_t PcmCrc[2] ; -uint8_t PcmOnesCount[2] ; - -void crc( uint8_t data, uint32_t module_index ) +void crc(uint8_t data, unsigned int port) { - // uint8_t i ; - - PcmCrc[module_index]=(PcmCrc[module_index]<<8)^(CRCTable[((PcmCrc[module_index]>>8)^data) & 0xFF]); + PcmCrc[port]=(PcmCrc[port]<<8)^(CRCTable[((PcmCrc[port]>>8)^data) & 0xFF]); } -void putPcmPart( uint8_t value, uint32_t module_index ) +void putPcmPart(uint8_t value, unsigned int port) { - PxxValue[module_index] += 18 ; // Output 1 for this time - *pxxStreamPtr[module_index]++ = PxxValue[module_index] ; - PxxValue[module_index] += 14 ; - if ( value ) { - PxxValue[module_index] += 16 ; + PxxValue[port] += 18 ; // Output 1 for this time + *pxxStreamPtr[port]++ = PxxValue[port] ; + PxxValue[port] += 14 ; + if (value) { + PxxValue[port] += 16 ; } - *pxxStreamPtr[module_index]++ = PxxValue[module_index] ; // Output 0 for this time + *pxxStreamPtr[port]++ = PxxValue[port] ; // Output 0 for this time } -void putPcmFlush( uint32_t module_index ) +void putPcmFlush(unsigned int port) { - *pxxStreamPtr[module_index]++ = 18010 ; // Past the 18000 of the ARR + *pxxStreamPtr[port]++ = 18010 ; // Past the 18000 of the ARR } -void putPcmBit( uint8_t bit, uint32_t module_index ) +void putPcmBit(uint8_t bit, unsigned int port) { - if ( bit ) + if (bit) { - PcmOnesCount[module_index] += 1 ; - putPcmPart( 1, module_index ) ; + PcmOnesCount[port] += 1 ; + putPcmPart(1, port); } else { - PcmOnesCount[module_index] = 0 ; - putPcmPart( 0, module_index ) ; + PcmOnesCount[port] = 0 ; + putPcmPart(0, port); } - if ( PcmOnesCount[module_index] >= 5 ) + if (PcmOnesCount[port] >= 5) { - putPcmBit( 0, module_index ) ; // Stuff a 0 bit in + putPcmBit(0, port); // Stuff a 0 bit in } } -void putPcmByte( uint8_t byte, uint32_t module_index ) +void putPcmByte(uint8_t byte, unsigned int port) { - crc(byte, module_index); + crc(byte, port); for (uint8_t i=0; i<8; i++) { - putPcmBit(byte & 0x80, module_index); + putPcmBit(byte & 0x80, port); byte <<= 1; } } -void putPcmHead( uint32_t module_index ) +void putPcmHead(unsigned int port) { // send 7E, do not CRC // 01111110 - putPcmPart( 0, module_index ) ; - putPcmPart( 1, module_index ) ; - putPcmPart( 1, module_index ) ; - putPcmPart( 1, module_index ) ; - putPcmPart( 1, module_index ) ; - putPcmPart( 1, module_index ) ; - putPcmPart( 1, module_index ) ; - putPcmPart( 0, module_index ) ; -} - -#else // Not Taranis -uint16_t PcmCrc ; -uint8_t PcmOnesCount ; - - -void crc( uint8_t data ) -{ - // uint8_t i ; - - PcmCrc=(PcmCrc<<8)^(CRCTable[((PcmCrc>>8)^data) & 0xFF]); + putPcmPart(0, port); + putPcmPart(1, port); + putPcmPart(1, port); + putPcmPart(1, port); + putPcmPart(1, port); + putPcmPart(1, port); + putPcmPart(1, port); + putPcmPart(0, port); } #if defined(PCBSKY9X) -void put_serial_bit( uint8_t bit ) +void put_serial_bit(uint8_t bit) { Serial_byte >>= 1 ; - if ( bit & 1 ) + if (bit & 1) { Serial_byte |= 0x80 ; } - if ( ++Serial_bit_count >= 8 ) + if (++Serial_bit_count >= 8) { *Pulses2MHzptr++ = Serial_byte ; Serial_bit_count = 0 ; Serial_byte_count += 1 ; } } - -// 8uS/bit 01 = 0, 001 = 1 -void putPcmPart( uint8_t value ) -{ - put_serial_bit( 0 ) ; - if ( value ) - { - put_serial_bit( 0 ) ; - } - put_serial_bit( 1 ) ; -} - -void putPcmFlush() -{ - while ( Serial_bit_count != 0 ) - { - put_serial_bit( 1 ) ; // Line idle level - } -} -#else -void putPcmPart( uint8_t value ) -{ - PxxValue += 18 ; // Output 1 for this time - *pxxStreamPtr++ = PxxValue ; - PxxValue += 14 ; - if ( value ) { - PxxValue += 16 ; - } - *pxxStreamPtr++ = PxxValue ; // Output 0 for this time -} - -void putPcmFlush() -{ - *pxxStreamPtr++ = 18010 ; // Past the 18000 of the ARR -} #endif -void putPcmBit( uint8_t bit ) -{ - if ( bit ) - { - PcmOnesCount += 1 ; - putPcmPart( 1 ) ; - } - else - { - PcmOnesCount = 0 ; - putPcmPart( 0 ) ; - } - if ( PcmOnesCount >= 5 ) - { - putPcmBit( 0 ) ; // Stuff a 0 bit in - } -} - -void putPcmByte( uint8_t byte ) -{ - crc(byte); - - for (uint8_t i=0; i<8; i++) { - putPcmBit(byte & 0x80); - byte <<= 1; - } -} - -void putPcmHead() -{ - // send 7E, do not CRC - // 01111110 - putPcmPart( 0 ) ; - putPcmPart( 1 ) ; - putPcmPart( 1 ) ; - putPcmPart( 1 ) ; - putPcmPart( 1 ) ; - putPcmPart( 1 ) ; - putPcmPart( 1 ) ; - putPcmPart( 0 ) ; -} -#endif // Taranis - -void setupPulsesPXX(MODULE_INDEX_PARAM) +void setupPulsesPXX(unsigned int port) { uint16_t chan=0, chan_low=0; -#if defined(PCBSKY9X) - Serial_byte = 0 ; - Serial_bit_count = 0 ; - Serial_byte_count = 0 ; - Pulses2MHzptr = Bit_pulses ; -#else - #if defined(PCBTARANIS) - pxxStreamPtr[module_index] = module_index ? pxx2Stream : pxxStream ; - PxxValue[module_index] = 0 ; - #else - pxxStreamPtr = pxxStream ; - PxxValue = 0 ; - #endif -#endif - #if defined(PCBTARANIS) - PcmCrc[module_index] = 0; - PcmOnesCount[module_index] = 0; - - /* Sync */ - putPcmHead(module_index); - - /* Rx Number */ - putPcmByte(g_model.header.modelId, module_index); -#else - PcmCrc = 0; - PcmOnesCount = 0; - - /* Sync */ - putPcmHead(); - - /* Rx Number */ - putPcmByte(g_model.header.modelId); + pxxStreamPtr[port] = pxxStream[port]; + PxxValue[port] = 0 ; #endif + PcmCrc[port] = 0; + PcmOnesCount[port] = 0; + + /* Sync */ + putPcmHead(port); + + /* Rx Number */ + putPcmByte(g_model.header.modelId, port); + /* FLAG1 */ uint8_t flag1; - if (pxxFlag[0] & PXX_SEND_RXNUM) { - - -#if defined(PCBTARANIS) - flag1 = (g_model.moduleData[module_index].rfProtocol << 6) | (g_eeGeneral.countryCode << 1) | pxxFlag[module_index]; + if (pxxFlag[port] & PXX_SEND_RXNUM) { + flag1 = (g_model.moduleData[port].rfProtocol << 6) | (g_eeGeneral.countryCode << 1) | pxxFlag[port]; } else { - flag1 = (g_model.moduleData[module_index].rfProtocol << 6) | pxxFlag[0]; -#else - flag1 = (g_model.moduleData[0].rfProtocol << 6) | (g_eeGeneral.countryCode << 1) | pxxFlag[0]; - } - else { - flag1 = (g_model.moduleData[0].rfProtocol << 6) | pxxFlag[0]; -#endif + flag1 = (g_model.moduleData[port].rfProtocol << 6) | pxxFlag[port]; -#if defined(PCBTARANIS) - if (g_model.moduleData[module_index].failsafeMode != FAILSAFE_HOLD) { - if (failsafeCounter-- == 0) { - failsafeCounter = 1000; + if (g_model.moduleData[port].failsafeMode != FAILSAFE_HOLD) { + if (failsafeCounter[port]-- == 0) { + failsafeCounter[port] = 1000; flag1 |= PXX_SEND_FAILSAFE; } - if (failsafeCounter == 0 && g_model.moduleData[module_index].channelsCount > 0) { + if (failsafeCounter[port] == 0 && g_model.moduleData[port].channelsCount > 0) { flag1 |= PXX_SEND_FAILSAFE; } } -#endif } -#if defined(PCBTARANIS) - putPcmByte(flag1, module_index); + + putPcmByte(flag1, port); /* FLAG2 */ - putPcmByte(0, module_index); -#else - putPcmByte(flag1); - - /* FLAG2 */ - putPcmByte(0); -#endif + putPcmByte(0, port); /* PPM */ static uint32_t pass = 0; uint32_t sendUpperChannels = 0; if (pass++ & 0x01) { -#if defined(PCBTARANIS) - sendUpperChannels = g_model.moduleData[module_index].channelsCount; -#else - sendUpperChannels = g_model.moduleData[0].channelsCount; -#endif + sendUpperChannels = g_model.moduleData[port].channelsCount; } for (uint32_t i=0; i<8; i++) { -#if defined(PCBTARANIS) if (flag1 & PXX_SEND_FAILSAFE) { - if (g_model.moduleData[module_index].failsafeMode == FAILSAFE_NOPULSES) { + if (g_model.moduleData[port].failsafeMode == FAILSAFE_NOPULSES) { if (i < sendUpperChannels) chan = 3072; else @@ -481,18 +309,16 @@ void setupPulsesPXX(MODULE_INDEX_PARAM) } else { if (i < sendUpperChannels) { - chan = limit(2048, PPM_CH_CENTER(8+g_model.moduleData[module_index].channelsStart+i) - PPM_CENTER + (g_model.moduleData[module_index].failsafeChannels[8+g_model.moduleData[0].channelsStart+i] * 512 / 682) + 3072, 4095); + chan = limit(2048, PPM_CH_CENTER(8+g_model.moduleData[port].channelsStart+i) - PPM_CENTER + (g_model.moduleData[port].failsafeChannels[8+g_model.moduleData[port].channelsStart+i] * 512 / 682) + 3072, 4095); if (chan == 3072) chan = 3073; } else { - chan = limit(0, PPM_CH_CENTER(g_model.moduleData[module_index].channelsStart+i) - PPM_CENTER + (g_model.moduleData[module_index].failsafeChannels[g_model.moduleData[0].channelsStart+i] * 512 / 682) + 1024, 2047); + chan = limit(0, PPM_CH_CENTER(g_model.moduleData[port].channelsStart+i) - PPM_CENTER + (g_model.moduleData[port].failsafeChannels[g_model.moduleData[port].channelsStart+i] * 512 / 682) + 1024, 2047); if (chan == 1024) chan = 1025; } } } - else -#endif - { + else { if (i < sendUpperChannels) chan = limit(2048, PPM_CH_CENTER(8+g_model.moduleData[0].channelsStart+i) - PPM_CENTER + (channelOutputs[8+g_model.moduleData[0].channelsStart+i] * 512 / 682) + 3072, 4095); else @@ -500,15 +326,9 @@ void setupPulsesPXX(MODULE_INDEX_PARAM) } if (i & 1) { -#if defined(PCBTARANIS) - putPcmByte(chan_low, module_index); // Low byte of channel - putPcmByte( ( ( chan_low >> 8 ) & 0x0F ) | ( chan << 4), module_index ) ; // 4 bits each from 2 channels - putPcmByte(chan >> 4, module_index); // High byte of channel -#else - putPcmByte(chan_low); // Low byte of channel - putPcmByte( ( ( chan_low >> 8 ) & 0x0F ) | ( chan << 4) ) ; // 4 bits each from 2 channels - putPcmByte(chan >> 4); // High byte of channel -#endif + putPcmByte(chan_low, port); // Low byte of channel + putPcmByte(((chan_low >> 8) & 0x0F) | (chan << 4), port); // 4 bits each from 2 channels + putPcmByte(chan >> 4, port); // High byte of channel } else { chan_low = chan; @@ -516,42 +336,30 @@ void setupPulsesPXX(MODULE_INDEX_PARAM) } /* CRC16 */ -#if defined(PCBTARANIS) - putPcmByte(0, module_index); - chan = PcmCrc[module_index]; - putPcmByte(chan>>8, module_index); - putPcmByte(chan, module_index); + putPcmByte(0, port); + chan = PcmCrc[port]; + putPcmByte(chan>>8, port); + putPcmByte(chan, port); /* Sync */ - putPcmHead(module_index); + putPcmHead(port); - putPcmFlush(module_index); -#else - putPcmByte(0); - chan = PcmCrc; - putPcmByte(chan>>8); - putPcmByte(chan); - - /* Sync */ - putPcmHead(); - - putPcmFlush(); -#endif + putPcmFlush(port); } #if defined(DSM2) #define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1 { - put_serial_bit( 0 ) ; // Start bit - for( uint8_t i=0; i<8; i++) // 8 data Bits + put_serial_bit(0) ; // Start bit + for(uint8_t i=0; i<8; i++) // 8 data Bits { - put_serial_bit( b & 1 ) ; + put_serial_bit(b & 1) ; b >>= 1 ; } - put_serial_bit( 1 ) ; // Stop bit - put_serial_bit( 1 ) ; // Stop bit + put_serial_bit(1) ; // Stop bit + put_serial_bit(1) ; // Stop bit } // This is the data stream to send, prepare after 19.5 mS @@ -572,7 +380,7 @@ void setupPulsesDsm2(uint8_t chns) // If more channels needed make sure the pulses union/array is large enough if (dsmDat[0]&BAD_DATA) //first time through, setup header { - switch(s_current_protocol) + switch(s_current_protocol[0]) { case PROTO_DSM2_LP45: dsmDat[0]= 0x80; @@ -597,13 +405,13 @@ void setupPulsesDsm2(uint8_t chns) dsmDat[3+2*i] = pulse & 0xff; } - for ( counter = 0 ; counter < 14 ; counter += 1 ) + for (counter = 0 ; counter < 14 ; counter += 1) { sendByteDsm2(dsmDat[counter]); } - for ( counter = 0 ; counter < 16 ; counter += 1 ) + for (counter = 0 ; counter < 16 ; counter += 1) { - put_serial_bit( 1 ) ; // 16 extra stop bits + put_serial_bit(1) ; // 16 extra stop bits } } #endif @@ -619,7 +427,7 @@ extern "C" void PWM_IRQHandler(void) pwmptr = PWM; reason = pwmptr->PWM_ISR1 ; if (reason & PWM_ISR1_CHID3) { - switch (s_current_protocol) // Use the current, don't switch until set_up_pulses + switch (s_current_protocol[0]) // Use the current, don't switch until set_up_pulses { case PROTO_PXX: // Alternate periods of 15.5mS and 2.5 mS @@ -632,10 +440,9 @@ extern "C" void PWM_IRQHandler(void) } pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = period; // Period in half uS if (period != 5000) { // 2.5 mS - setupPulses(); + setupPulses(INTERNAL_MODULE); } else { - // Kick off serial output here sscptr = SSC; sscptr->SSC_TPR = (uint32_t) Bit_pulses; @@ -659,7 +466,7 @@ extern "C" void PWM_IRQHandler(void) pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = period; // Period in half uS if (period != 5000) // 2.5 mS { - setupPulses(); + setupPulses(0); } else { // Kick off serial output here @@ -671,10 +478,10 @@ extern "C" void PWM_IRQHandler(void) break; default: - pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = ppmStream[ppmStreamIndex++]; // Period in half uS - if (ppmStream[ppmStreamIndex] == 0) { - ppmStreamIndex = 0; - setupPulses(); + pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = ppmStream[0][ppmStreamIndex[0]++]; // Period in half uS + if (ppmStream[0][ppmStreamIndex[0]] == 0) { + ppmStreamIndex[0] = 0; + setupPulses(0); } break; @@ -682,25 +489,38 @@ extern "C" void PWM_IRQHandler(void) } if (reason & PWM_ISR1_CHID1) { - pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = ppm2Stream[ppm2StreamIndex++] ; // Period in half uS - if (ppm2Stream[ppm2StreamIndex] == 0) { - ppm2StreamIndex = 0 ; + pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = ppmStream[1][ppmStreamIndex[1]++] ; // Period in half uS + if (ppmStream[1][ppmStreamIndex[1]] == 0) { + ppmStreamIndex[1] = 0 ; setupPulsesPPM(1) ; } } } #endif -void setupPulses(MODULE_INDEX_PARAM) +void setupPulses(unsigned int port) { - heartbeat |= HEART_TIMER_PULSES; + heartbeat |= (HEART_TIMER_PULSES << port); #if defined(PCBTARANIS) - if ( module_index ) - { - module_index = 1 ; // Ensure is 0 or 1 only - } - uint8_t required_protocol = (g_model.moduleData[module_index].rfProtocol == RF_PROTO_OFF ? PROTO_NONE : PROTO_PXX); + if (port) port = 1; // Ensure is 0 or 1 only + uint8_t required_protocol; + + if (port == INTERNAL_MODULE) + required_protocol = g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF ? PROTO_NONE : PROTO_PXX; + else { + switch (g_model.externalModule) { + case MODULE_TYPE_PPM: + required_protocol = PROTO_PPM; + break; + case MODULE_TYPE_XJT: + case MODULE_TYPE_DJT: + required_protocol = PROTO_PXX; + break; + default: + required_protocol = PROTO_NONE; + } + } #else uint8_t required_protocol = g_model.protocol; #endif @@ -708,12 +528,12 @@ void setupPulses(MODULE_INDEX_PARAM) if (s_pulses_paused) required_protocol = PROTO_NONE; - if (s_current_protocol != required_protocol) { + if (s_current_protocol[port] != required_protocol) { - switch (s_current_protocol) { // stop existing protocol hardware + switch (s_current_protocol[port]) { // stop existing protocol hardware case PROTO_PXX: #if defined(PCBTARANIS) - disable_pxx(module_index); + disable_pxx(port); #else disable_pxx(); #endif @@ -727,24 +547,22 @@ void setupPulses(MODULE_INDEX_PARAM) #endif default: #if defined(PCBTARANIS) - disable_ppm(module_index); + disable_ppm(port); #else disable_main_ppm(); #endif break; } - s_current_protocol = required_protocol; + s_current_protocol[port] = required_protocol; #if defined(PCBTARANIS) switch (required_protocol) { case PROTO_PXX: - init_pxx(0); -// init_pxx(module_index); + init_pxx(port); break; - default: - init_ppm(0); -// init_ppm(module_index); + case PROTO_PPM: + init_ppm(port); break; } #elif defined(PCBSKY9X) @@ -772,11 +590,7 @@ void setupPulses(MODULE_INDEX_PARAM) // Set up output data here switch (required_protocol) { case PROTO_PXX: -#if defined(PCBTARANIS) - setupPulsesPXX(module_index); -#else - setupPulsesPXX(); -#endif + setupPulsesPXX(port); break; #if defined(DSM2) case PROTO_DSM2_LP45: @@ -785,8 +599,12 @@ void setupPulses(MODULE_INDEX_PARAM) setupPulsesDsm2(6); break; #endif +#if defined(PCBTARANIS) + case PROTO_PPM: +#else default: - setupPulsesPPM(); // Don't enable interrupts through here +#endif + setupPulsesPPM(port); // Don't enable interrupts through here break ; } } diff --git a/src/pulses_arm.h b/src/pulses_arm.h index 4ab57cb0b..b8a1c8089 100644 --- a/src/pulses_arm.h +++ b/src/pulses_arm.h @@ -37,16 +37,35 @@ #ifndef pulses_arm_h #define pulses_arm_h -extern uint8_t s_current_protocol; +extern uint8_t s_current_protocol[NUM_MODULES]; extern uint8_t s_pulses_paused; -extern uint32_t failsafeCounter; +extern uint32_t failsafeCounter[NUM_MODULES]; -void startPulses(); -inline bool pulsesStarted() { return s_current_protocol != 255; } +void setupPulses(unsigned int port); +void setupPulsesDsm2(uint8_t chns); +void setupPulsesPXX(unsigned int port); +void setupPulsesPPM(unsigned int port); + +inline void startPulses() +{ +#if defined(PCBTARANIS) + setupPulses(INTERNAL_MODULE); + setupPulses(EXTERNAL_MODULE); +#else + setupPulses(0); +#endif +} + +inline bool pulsesStarted() { return s_current_protocol[0] != 255; } inline void pausePulses() { s_pulses_paused = true; } inline void resumePulses() { s_pulses_paused = false; } -#define SEND_FAILSAFE_NOW() failsafeCounter = 1 -#define SEND_FAILSAFE_1S() failsafeCounter = 100 +#define SEND_FAILSAFE_NOW(idx) failsafeCounter[idx] = 1 + +inline void SEND_FAILSAFE_1S() +{ + for (int i=0; iPWM_CH_NUM[3].PWM_CMR = 0x0000000B ; // CLKA - if (g_model.pulsePol) + if (g_model.moduleData[0].ppmPulsePol) pwmptr->PWM_CH_NUM[3].PWM_CMR |= 0x00000200 ; // CPOL 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 = g_model.ppmDelay*100+600; // Duty in half uS - pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = g_model.ppmDelay*100+600; // Duty in half uS + pwmptr->PWM_CH_NUM[3].PWM_CDTY = g_model.moduleData[0].ppmDelay*100+600; // Duty in half uS + pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = g_model.moduleData[0].ppmDelay*100+600; // Duty in half uS pwmptr->PWM_ENA = PWM_ENA_CHID3 ; // Enable channel 3 pwmptr->PWM_IER1 = PWM_IER1_CHID3 ; @@ -70,12 +70,12 @@ void init_main_ppm( uint32_t period, uint32_t out_enable ) #if !defined(REVA) // PWM1 for PPM2 pwmptr->PWM_CH_NUM[1].PWM_CMR = 0x0000000B ; // CLKB - if (g_model.pulsePol) + if (g_model.moduleData[0].ppmPulsePol) 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 = g_model.ppmDelay*100+600 ; // Duty - pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = g_model.ppmDelay*100+600 ; // Duty + pwmptr->PWM_CH_NUM[1].PWM_CDTY = g_model.moduleData[0].ppmDelay*100+600 ; // Duty + pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = g_model.moduleData[0].ppmDelay*100+600 ; // Duty pwmptr->PWM_ENA = PWM_ENA_CHID1 ; // Enable channel 1 #endif diff --git a/src/taranis/board_taranis.cpp b/src/taranis/board_taranis.cpp index 962b821c0..f44423529 100644 --- a/src/taranis/board_taranis.cpp +++ b/src/taranis/board_taranis.cpp @@ -210,25 +210,11 @@ void boardInit() #if defined(DEBUG) uartInit(DEBUG_UART_BAUDRATE); #endif - - // TODO init_ppm() ; - - init_trainer_capture() ; - init5msTimer(); - __enable_irq() ; + init_trainer_capture(); init5msTimer(); + __enable_irq(); eepromInit(); sportInit(); usbInit(); - - //Temporary: Configure second PPM pin as input (done after USB init in case the lib already initialises USB_ID) -// GPIO_InitTypeDef GPIO_InitStructure; -// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_EXTPPM, ENABLE); -// GPIO_InitStructure.GPIO_Pin = PIN_EXTPPM_OUT; -// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; -// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; -// GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; -// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; -// GPIO_Init(GPIO_EXTPPM, &GPIO_InitStructure); } #endif diff --git a/src/taranis/board_taranis.h b/src/taranis/board_taranis.h index 39c4da539..601213ac8 100644 --- a/src/taranis/board_taranis.h +++ b/src/taranis/board_taranis.h @@ -123,7 +123,7 @@ void disable_pxx( uint32_t module_index ); void init_trainer_ppm(); void stop_trainer_ppm(); void init_trainer_capture(); -void stop_trainer_ppm() ; +void stop_trainer_capture(); // Keys driver void keysInit(); diff --git a/src/taranis/hal.h b/src/taranis/hal.h index 73cd1dbdd..7d4fe9728 100644 --- a/src/taranis/hal.h +++ b/src/taranis/hal.h @@ -178,14 +178,14 @@ // #define PIN_OS100 0x6000 // Cppm -#define RCC_AHB1Periph_GPIOCPPM RCC_AHB1Periph_GPIOA -#define PIN_CPPM_OUT GPIO_Pin_7 //PA.07 -#define GPIOCPPM GPIOA -#define GPIO_PinSource_CPPM GPIO_PinSource7 +#define RCC_AHB1Periph_GPIO_INTPPM RCC_AHB1Periph_GPIOA +#define PIN_INTPPM_OUT GPIO_Pin_10 //PA.10 +#define GPIO_INTPPM GPIOA +#define GPIO_PinSource_INTPPM GPIO_PinSource10 #define RCC_AHB1Periph_GPIO_EXTPPM RCC_AHB1Periph_GPIOA -#define PIN_EXTPPM_OUT GPIO_Pin_10 //PA.10 +#define PIN_EXTPPM_OUT GPIO_Pin_7 //PA.07 #define GPIO_EXTPPM GPIOA -#define GPIO_PinSource_EXTPPM GPIO_PinSource10 +#define GPIO_PinSource_EXTPPM GPIO_PinSource7 // Heart Beat #define PIN_HEART_BEAT GPIO_Pin_7 //PC.07 @@ -216,7 +216,6 @@ // USB_OTG #define PIN_FS_VBUS GPIO_Pin_9 //PA.09 -#define PIN_FS_ID GPIO_Pin_10 //PA.10 #define PIN_FS_DM GPIO_Pin_11 //PA.11 #define PIN_FS_DP GPIO_Pin_12 //PA.12 diff --git a/src/taranis/pulses_driver.cpp b/src/taranis/pulses_driver.cpp index 7cdbaf903..f847f7bd5 100644 --- a/src/taranis/pulses_driver.cpp +++ b/src/taranis/pulses_driver.cpp @@ -36,24 +36,15 @@ #include "../opentx.h" -#define EXTERNAL_TEST 0 - // CURRENTLY EXPECTS ONLY PXX ON THE INTERNAL SIGNAL, PPM ALLOWED ON THE EXTERNAL SIGNAL -// TODO not here! -void setupPulses( uint32_t module ); -void setupPulsesPPM() ; -void setupPulsesPXX( uint32_t module ); +void setupPulses(unsigned int port); +void setupPulsesPPM(unsigned int port); +void setupPulsesPXX(unsigned int port); -uint16_t *ppmStreamPtr; -uint16_t *ppm2StreamPtr; -extern uint16_t ppmStream[20]; -extern uint16_t ppm2Stream[20]; -extern uint16_t pxxStream[400] ; -extern uint16_t pxx2Stream[400] ; - -#define INT_MODULE 0 -#define EXT_MODULE 0 +uint16_t *ppmStreamPtr[NUM_MODULES]; +extern uint16_t ppmStream[NUM_MODULES][20]; +extern uint16_t pxxStream[NUM_MODULES][400] ; static void init_pa10_pxx( void ) ; static void disable_pa10_pxx( void ) ; @@ -64,75 +55,58 @@ static void disable_pa7_pxx( void ) ; static void init_pa7_ppm( void ) ; static void disable_pa7_ppm( void ) ; -void init_pxx( uint32_t module_index ) +void init_pxx(uint32_t port) { - if ( module_index ) - { - init_pa10_pxx() ; - } - else - { - init_pa7_pxx() ; - } + if (port == INTERNAL_MODULE) + init_pa10_pxx() ; + else + init_pa7_pxx() ; } -void disable_pxx( uint32_t module_index ) +void disable_pxx(uint32_t port) { - if ( module_index ) - { - disable_pa10_pxx() ; - } - else - { - disable_pa7_pxx() ; - } + if (port == INTERNAL_MODULE) + disable_pa10_pxx() ; + else + disable_pa7_pxx() ; } -void init_ppm( uint32_t module_index ) +void init_ppm(uint32_t port) { - if ( module_index ) - { - init_pa10_ppm() ; - } - else - { - init_pa7_ppm() ; - } + if (port == INTERNAL_MODULE) + init_pa10_ppm(); + else + init_pa7_ppm(); } -void disable_ppm( uint32_t module_index ) +void disable_ppm(uint32_t port) { - if ( module_index ) - { - disable_pa10_ppm() ; - } - else - { - disable_pa7_ppm() ; - } + if (port == INTERNAL_MODULE) + disable_pa10_ppm(); + else + disable_pa7_ppm(); } - static void init_pa10_pxx() { - EXTERNAL_RF_ON(); + INTERNAL_RF_ON(); // Timer1, channel 3 - setupPulsesPXX(EXT_MODULE) ; // TODO not here! + setupPulsesPXX(INTERNAL_MODULE) ; // TODO not here! - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock +// RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock GPIO_InitTypeDef GPIO_InitStructure; -// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOCPPM, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_INTPPM, ENABLE); - GPIO_PinAFConfig(GPIO_EXTPPM, GPIO_PinSource_EXTPPM, GPIO_AF_TIM1); - GPIO_InitStructure.GPIO_Pin = PIN_EXTPPM_OUT; + GPIO_PinAFConfig(GPIO_INTPPM, GPIO_PinSource_INTPPM, GPIO_AF_TIM1); + GPIO_InitStructure.GPIO_Pin = PIN_INTPPM_OUT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOCPPM, &GPIO_InitStructure); + GPIO_Init(GPIO_INTPPM, &GPIO_InitStructure); - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN ; // Enable DMA2 clock TIM1->CR1 &= ~TIM_CR1_CEN ; @@ -140,11 +114,11 @@ static void init_pa10_pxx() TIM1->CCR2 = 15000 ; // Update time TIM1->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz - TIM1->CCER = TIM_CCER_CC3E ; + TIM1->CCER = TIM_CCER_CC3E ; - TIM1->CR2 = TIM_CR2_OIS3 ; // O/P idle high + TIM1->CR2 = TIM_CR2_OIS3 ; // O/P idle high TIM1->BDTR = TIM_BDTR_MOE ; // Enable outputs - TIM1->CCR3 = pxxStream[0] ; + TIM1->CCR3 = pxxStream[INTERNAL_MODULE][0]; TIM1->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0 ; // Force O/P high TIM1->EGR = 1 ; // Restart @@ -154,13 +128,13 @@ static void init_pa10_pxx() TIM1->DCR = 15 ; // DMA to CC1 // TIM1->CR1 = TIM_CR1_OPM ; // Just run once - // Enable the DMA channel here, DMA2 stream 6, channel 6 + // Enable the DMA channel here, DMA2 stream 6, channel 6 DMA2_Stream6->CR &= ~DMA_SxCR_EN ; // Disable DMA DMA2->HIFCR = DMA_HIFCR_CTCIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6 ; // Write ones to clear bits DMA2_Stream6->CR = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL ; DMA2_Stream6->PAR = CONVERT_PTR(&TIM1->DMAR); - DMA2_Stream6->M0AR = CONVERT_PTR(&pxxStream[1]); + DMA2_Stream6->M0AR = CONVERT_PTR(&pxxStream[INTERNAL_MODULE][1]); // DMA2_Stream2->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ; // DMA2_Stream2->NDTR = 100 ; DMA2_Stream6->CR |= DMA_SxCR_EN ; // Enable DMA @@ -179,7 +153,7 @@ static void disable_pa10_pxx() NVIC_DisableIRQ(TIM1_CC_IRQn) ; TIM1->DIER &= ~TIM_DIER_CC2IE ; TIM1->CR1 &= ~TIM_CR1_CEN ; - EXTERNAL_RF_OFF(); + INTERNAL_RF_OFF(); } // PPM output @@ -187,26 +161,27 @@ static void disable_pa10_pxx() // Pin is AF1 function for timer 1 static void init_pa10_ppm() { - EXTERNAL_RF_ON(); + INTERNAL_RF_ON(); // Timer1 - setupPulsesPPM() ; - ppmStreamPtr = ppmStream ; + setupPulsesPPM(INTERNAL_MODULE) ; + ppmStreamPtr[INTERNAL_MODULE] = ppmStream[INTERNAL_MODULE]; - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock + //RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_INTPPM, ENABLE); - configure_pins( PIN_EXTPPM_OUT, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_1 | PIN_OS25 | PIN_PUSHPULL ) ; + configure_pins( PIN_INTPPM_OUT, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_1 | PIN_OS25 | PIN_PUSHPULL ) ; - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock TIM1->CR1 &= ~TIM_CR1_CEN ; - TIM1->ARR = *ppmStreamPtr++ ; + TIM1->ARR = *ppmStreamPtr[INTERNAL_MODULE]++ ; TIM1->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz - TIM1->CCER = TIM_CCER_CC3E ; + TIM1->CCER = TIM_CCER_CC3E ; - TIM1->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 ; // PWM mode 1 + TIM1->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 ; // PWM mode 1 TIM1->CCMR1 = TIM_CCMR1_OC2PE ; // PWM mode 1 - TIM1->CCR3 = 600 ; // 300 uS pulse ?? (g_model.ppmDelay*50+300)*2 ?? + TIM1->CCR3 = (g_model.moduleData[INTERNAL_MODULE].ppmDelay*50+300)*2; TIM1->BDTR = TIM_BDTR_MOE ; TIM1->EGR = 1 ; TIM1->DIER = TIM_DIER_UDE ; @@ -227,18 +202,8 @@ static void disable_pa10_ppm() NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn) ; TIM1->DIER &= ~TIM_DIER_CC2IE & ~TIM_DIER_UIE ; TIM1->CR1 &= ~TIM_CR1_CEN ; - - // Make pin an input - GPIO_InitTypeDef GPIO_InitStructure; - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_EXTPPM, ENABLE); - GPIO_InitStructure.GPIO_Pin = PIN_EXTPPM_OUT; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIO_EXTPPM, &GPIO_InitStructure); - EXTERNAL_RF_OFF(); + INTERNAL_RF_OFF(); } extern "C" void TIM1_CC_IRQHandler() @@ -246,18 +211,18 @@ extern "C" void TIM1_CC_IRQHandler() TIM1->DIER &= ~TIM_DIER_CC2IE ; // stop this interrupt TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag - setupPulses(1) ; + setupPulses(INTERNAL_MODULE) ; - if (s_current_protocol == PROTO_PXX) { + if (s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) { DMA2_Stream6->CR &= ~DMA_SxCR_EN ; // Disable DMA - DMA2->HIFCR = DMA_HIFCR_CTCIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6 ; // Write ones to clear bits - DMA2_Stream6->M0AR = CONVERT_PTR(&pxxStream[1]); + DMA2->HIFCR = DMA_HIFCR_CTCIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6 ; // Write ones to clear bits + DMA2_Stream6->M0AR = CONVERT_PTR(&pxxStream[INTERNAL_MODULE][1]); DMA2_Stream6->CR |= DMA_SxCR_EN ; // Enable DMA - TIM1->CCR3 = pxxStream[0] ; + TIM1->CCR3 = pxxStream[INTERNAL_MODULE][0]; TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt } else { - ppmStreamPtr = ppmStream ; + ppmStreamPtr[INTERNAL_MODULE] = ppmStream[INTERNAL_MODULE]; TIM1->DIER |= TIM_DIER_UDE ; TIM1->SR &= ~TIM_SR_UIF ; // Clear this flag @@ -269,40 +234,34 @@ extern "C" void TIM1_UP_TIM10_IRQHandler() { TIM1->SR &= ~TIM_SR_UIF ; // Clear flag - TIM1->ARR = *ppmStreamPtr++ ; - if ( *ppmStreamPtr == 0 ) + TIM1->ARR = *ppmStreamPtr[INTERNAL_MODULE]++ ; + if ( *ppmStreamPtr[INTERNAL_MODULE] == 0 ) { TIM1->SR &= ~TIM_SR_CC2IF ; // Clear this flag TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt } } - - static void init_pa7_pxx() { -#if EXTERNAL_TEST - init_pa10_pxx() ; - return ; -#endif - INTERNAL_RF_ON(); + EXTERNAL_RF_ON(); // Timer8 - setupPulsesPXX(INT_MODULE) ; // TODO not here! + setupPulsesPXX(EXTERNAL_MODULE); RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock #if defined(REV3) - configure_pins( PIN_CPPM_OUT, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_1 | PIN_OS25 | PIN_PUSHPULL ) ; + configure_pins( PIN_INTPPM_OUT, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_1 | PIN_OS25 | PIN_PUSHPULL ) ; #else GPIO_InitTypeDef GPIO_InitStructure; - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOCPPM, ENABLE); - GPIO_PinAFConfig(GPIOCPPM, GPIO_PinSource_CPPM, GPIO_AF_TIM8); - GPIO_InitStructure.GPIO_Pin = PIN_CPPM_OUT; + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_EXTPPM, ENABLE); + GPIO_PinAFConfig(GPIO_EXTPPM, GPIO_PinSource_EXTPPM, GPIO_AF_TIM8); + GPIO_InitStructure.GPIO_Pin = PIN_EXTPPM_OUT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOCPPM, &GPIO_InitStructure); + GPIO_Init(GPIO_EXTPPM, &GPIO_InitStructure); #endif RCC->APB2ENR |= RCC_APB2ENR_TIM8EN ; // Enable clock RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN ; // Enable DMA2 clock @@ -318,7 +277,7 @@ static void init_pa7_pxx() #endif TIM8->CR2 = TIM_CR2_OIS1 ; // O/P idle high TIM8->BDTR = TIM_BDTR_MOE ; // Enable outputs - TIM8->CCR1 = pxxStream[0] ; + TIM8->CCR1 = pxxStream[EXTERNAL_MODULE][0] ; TIM8->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0 ; // Force O/P high TIM8->EGR = 1 ; // Restart @@ -334,7 +293,7 @@ static void init_pa7_pxx() DMA2_Stream2->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL ; DMA2_Stream2->PAR = CONVERT_PTR(&TIM8->DMAR); - DMA2_Stream2->M0AR = CONVERT_PTR(&pxxStream[1]); + DMA2_Stream2->M0AR = CONVERT_PTR(&pxxStream[EXTERNAL_MODULE][1]); // DMA2_Stream2->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ; // DMA2_Stream2->NDTR = 100 ; DMA2_Stream2->CR |= DMA_SxCR_EN ; // Enable DMA @@ -349,15 +308,11 @@ static void init_pa7_pxx() static void disable_pa7_pxx() { -#if EXTERNAL_TEST - disable_pa10_pxx() ; - return ; -#endif DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA NVIC_DisableIRQ(TIM8_CC_IRQn) ; TIM8->DIER &= ~TIM_DIER_CC2IE ; TIM8->CR1 &= ~TIM_CR1_CEN ; - INTERNAL_RF_OFF(); + EXTERNAL_RF_OFF(); } // PPM output @@ -365,26 +320,22 @@ static void disable_pa7_pxx() // Pin is AF1 function for timer 1 static void init_pa7_ppm() { -#if EXTERNAL_TEST - init_pa10_ppm() ; - return ; -#endif - INTERNAL_RF_ON(); + EXTERNAL_RF_ON(); // Timer1 - setupPulsesPPM() ; - ppmStreamPtr = ppmStream ; + setupPulsesPPM(EXTERNAL_MODULE) ; + ppmStreamPtr[EXTERNAL_MODULE] = ppmStream[EXTERNAL_MODULE]; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock #if defined(REV3) configure_pins( 0x0100, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_1 | PIN_OS25 | PIN_PUSHPULL ) ; #else - configure_pins( 0x0080, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_3 | PIN_OS25 | PIN_PUSHPULL ) ; + configure_pins( PIN_EXTPPM_OUT, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_3 | PIN_OS25 | PIN_PUSHPULL ) ; #endif RCC->APB2ENR |= RCC_APB2ENR_TIM8EN ; // Enable clock TIM8->CR1 &= ~TIM_CR1_CEN ; - TIM8->ARR = *ppmStreamPtr++ ; + TIM8->ARR = *ppmStreamPtr[EXTERNAL_MODULE]++ ; TIM8->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz #if defined(REV3) TIM8->CCER = TIM_CCER_CC1E ; @@ -392,7 +343,7 @@ static void init_pa7_ppm() TIM8->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1NP ; #endif TIM8->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE ; // PWM mode 1 - TIM8->CCR1 = 600 ; // 300 uS pulse ?? (g_model.ppmDelay*50+300)*2 ?? + TIM8->CCR1 = (g_model.moduleData[EXTERNAL_MODULE].ppmDelay*50+300)*2; TIM8->BDTR = TIM_BDTR_MOE ; TIM8->EGR = 1 ; TIM8->DIER = TIM_DIER_UDE ; @@ -409,15 +360,11 @@ static void init_pa7_ppm() static void disable_pa7_ppm() { -#if EXTERNAL_TEST - disable_pa10_ppm() ; - return ; -#endif NVIC_DisableIRQ(TIM8_CC_IRQn) ; NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn) ; TIM8->DIER &= ~TIM_DIER_CC2IE & ~TIM_DIER_UIE ; TIM8->CR1 &= ~TIM_CR1_CEN ; - INTERNAL_RF_OFF(); + EXTERNAL_RF_OFF(); } extern "C" void TIM8_CC_IRQHandler() @@ -425,18 +372,18 @@ extern "C" void TIM8_CC_IRQHandler() TIM8->DIER &= ~TIM_DIER_CC2IE ; // stop this interrupt TIM8->SR &= ~TIM_SR_CC2IF ; // Clear flag - setupPulses(INT_MODULE) ; + setupPulses(EXTERNAL_MODULE) ; - if (s_current_protocol == PROTO_PXX) { + if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) { DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 ; // Write ones to clear bits - DMA2_Stream2->M0AR = CONVERT_PTR(&pxxStream[1]); + DMA2_Stream2->M0AR = CONVERT_PTR(&pxxStream[EXTERNAL_MODULE][1]); DMA2_Stream2->CR |= DMA_SxCR_EN ; // Enable DMA - TIM8->CCR1 = pxxStream[0] ; + TIM8->CCR1 = pxxStream[EXTERNAL_MODULE][0] ; TIM8->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt } else { - ppmStreamPtr = ppmStream ; + ppmStreamPtr[EXTERNAL_MODULE] = ppmStream[EXTERNAL_MODULE]; TIM8->DIER |= TIM_DIER_UDE ; TIM8->SR &= ~TIM_SR_UIF ; // Clear this flag @@ -448,8 +395,8 @@ extern "C" void TIM8_UP_TIM13_IRQHandler() { TIM8->SR &= ~TIM_SR_UIF ; // Clear flag - TIM8->ARR = *ppmStreamPtr++ ; - if ( *ppmStreamPtr == 0 ) + TIM8->ARR = *ppmStreamPtr[EXTERNAL_MODULE]++ ; + if (*ppmStreamPtr[EXTERNAL_MODULE] == 0) { TIM8->SR &= ~TIM_SR_CC2IF ; // Clear this flag TIM8->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt diff --git a/src/taranis/trainer_driver.cpp b/src/taranis/trainer_driver.cpp index 885d34849..70cc8fef2 100644 --- a/src/taranis/trainer_driver.cpp +++ b/src/taranis/trainer_driver.cpp @@ -52,28 +52,32 @@ uint16_t TrainerPpmStream[20] = uint16_t * TrainerPulsePtr; +// TODO remove duplicated code void setupTrainerPulses() { int16_t PPM_range = g_model.extendedLimits ? 640 * 2 : 512 * 2; //range of 0.7..1.7msec uint16_t *ptr ; - uint32_t p = NUM_CHANNELS(0); + uint32_t firstCh = g_model.moduleData[TRAINER_MODULE].channelsStart; + uint32_t lastCh = min(NUM_CHNOUT, firstCh + 8 + g_model.moduleData[TRAINER_MODULE].channelsCount); ptr = TrainerPpmStream ; uint32_t rest = 22500u * 2; //Minimum Framelen=22.5 ms - rest += int32_t(g_model.ppmFrameLength) * 1000; + rest += int32_t(g_model.moduleData[TRAINER_MODULE].ppmFrameLength) * 1000; - for (uint32_t i = 0 ; i < p ; i += 1 ) { + for (uint32_t i=firstCh; i 65535) ? 65535 : rest; *ptr++ = rest ; *ptr = 0 ; TIM3->CCR2 = rest - 1000 ; // Update time - TIM3->CCR4 = (g_model.ppmDelay*50+300)*2 ; + TIM3->CCR4 = (g_model.moduleData[TRAINER_MODULE].ppmDelay*50+300)*2 ; } // Trainer PPM oputput PC9, Timer 3 channel 4, (Alternate Function 2) @@ -148,57 +152,54 @@ extern "C" void TIM3_IRQHandler() uint16_t val ; // What mode? in or out? - if ( (TIM3->DIER & TIM_DIER_CC3IE ) && ( TIM3->SR & TIM_SR_CC3IF ) ) - { - // capture mode - capture = TIM3->CCR3 ; + if ( (TIM3->DIER & TIM_DIER_CC3IE ) && ( TIM3->SR & TIM_SR_CC3IF ) ) { + // capture mode + capture = TIM3->CCR3 ; - val = (uint16_t)(capture - lastCapt) / 2 ; - lastCapt = capture; + val = (uint16_t)(capture - lastCapt) / 2 ; + lastCapt = capture; - // We prcoess g_ppmInsright here to make servo movement as smooth as possible - // while under trainee control - if ((val>4000) && (val < 19000)) { // G: Prioritize reset pulse. (Needed when less than 8 incoming pulses) - ppmInState = 1; // triggered - } - else { - if(ppmInState && (ppmInState<=8)) { - if ((val>800) && (val<2200)) { - g_ppmIns[ppmInState++ - 1] = (int16_t)(val - 1500)*(g_eeGeneral.PPM_Multiplier+10)/10; //+-500 != 512, but close enough. - } - else { - ppmInState = 0; // not triggered - } - } - } - } - // PPM out compare interrupt - if ( ( TIM3->DIER & TIM_DIER_CC2IE ) && ( TIM3->SR & TIM_SR_CC2IF ) ) - { // compare interrupt - TIM3->SR &= ~TIM_SR_CC2IF ; // Clear flag - TIM3->DIER &= ~TIM_DIER_CC2IE ; // stop this interrupt - TIM3->SR &= ~TIM_SR_CC2IF ; // Clear flag + // We prcoess g_ppmInsright here to make servo movement as smooth as possible + // while under trainee control + if ((val>4000) && (val < 19000)) { // G: Prioritize reset pulse. (Needed when less than 8 incoming pulses) + ppmInState = 1; // triggered + } + else { + if(ppmInState && (ppmInState<=8)) { + if ((val>800) && (val<2200)) { + g_ppmIns[ppmInState++ - 1] = (int16_t)(val - 1500)*(g_eeGeneral.PPM_Multiplier+10)/10; //+-500 != 512, but close enough. + } + else { + ppmInState = 0; // not triggered + } + } + } + } - setupTrainerPulses() ; + // PPM out compare interrupt + if ( ( TIM3->DIER & TIM_DIER_CC2IE ) && ( TIM3->SR & TIM_SR_CC2IF ) ) + { // compare interrupt + TIM3->SR &= ~TIM_SR_CC2IF ; // Clear flag + TIM3->DIER &= ~TIM_DIER_CC2IE ; // stop this interrupt + TIM3->SR &= ~TIM_SR_CC2IF ; // Clear flag - TrainerPulsePtr = TrainerPpmStream ; - TIM3->DIER |= TIM_DIER_UDE ; + setupTrainerPulses() ; - TIM3->SR &= ~TIM_SR_UIF ; // Clear this flag - TIM3->DIER |= TIM_DIER_UIE ; // Enable this interrupt - } - - // PPM out update interrupt - if ( (TIM3->DIER & TIM_DIER_UIE) && ( TIM3->SR & TIM_SR_UIF ) ) - { - TIM3->SR &= ~TIM_SR_UIF ; // Clear flag + TrainerPulsePtr = TrainerPpmStream ; + TIM3->DIER |= TIM_DIER_UDE ; - TIM3->ARR = *TrainerPulsePtr++ ; - if ( *TrainerPulsePtr == 0 ) - { - TIM3->SR &= ~TIM_SR_CC2IF ; // Clear this flag - TIM3->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt - } - } + TIM3->SR &= ~TIM_SR_UIF ; // Clear this flag + TIM3->DIER |= TIM_DIER_UIE ; // Enable this interrupt + } + + // PPM out update interrupt + if ( (TIM3->DIER & TIM_DIER_UIE) && ( TIM3->SR & TIM_SR_UIF ) ) { + TIM3->SR &= ~TIM_SR_UIF ; // Clear flag + TIM3->ARR = *TrainerPulsePtr++ ; + if ( *TrainerPulsePtr == 0 ) { + TIM3->SR &= ~TIM_SR_CC2IF ; // Clear this flag + TIM3->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt + } + } }