From 805a5352384c58e600ede377f5ff47f7e8bd8290 Mon Sep 17 00:00:00 2001 From: mike501 <60474160+mike501@users.noreply.github.com> Date: Mon, 15 May 2023 05:15:46 +0100 Subject: [PATCH] VVT2 improved logging & setup (#1036) * adding VVT logging and trigger edge editing fix missing define (temp fix?) Revert "fix missing define (temp fix?)" This reverts commit c6280f38ff69cc41278148a79c888736a71754b1. fixes * Create an additional logger screen in tunerstudio Changes to create a third high speed logger window in tuner studio. * Change variable name Discord discussion requested compositeLogEnabled didn't do a test for false as the type is now a byte. Variable renamed to be compositeTriggerUsed and false replaced with 0. Variable name and values used should now make more logical sense. * added more logging Log the primary, secondary and third inputs as well as engine cycle on all composite logs. Still have 3 different logs to allow you to visualise which is the best way to present the information. --- reference/speeduino.ini | 68 ++++++++++++++++++++- speeduino/comms.cpp | 22 ++++++- speeduino/comms_legacy.cpp | 20 ++++++- speeduino/decoders.h | 6 +- speeduino/decoders.ino | 117 +++++++++++++++++++++++++++++++------ speeduino/globals.h | 11 +++- speeduino/globals.ino | 2 + speeduino/init.ino | 3 + speeduino/logger.h | 6 ++ speeduino/logger.ino | 61 ++++++++++++++++++- speeduino/speeduino.ino | 2 +- 11 files changed, 287 insertions(+), 31 deletions(-) diff --git a/reference/speeduino.ini b/reference/speeduino.ini index c953b8fa..9cf552c5 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -3203,9 +3203,10 @@ menuDialog = main dialog = vvt2, "Second VVT output" field = "VVT2 Control Enabled", vvt2Enabled field = "VVT2 output pin", vvt2Pin, { vvt2Enabled } + field = "VVT2 Trigger edge", TrigEdgeThrd, { vvt2Enabled } field = "Increased duty direction",vvt2PWMdir, { vvt2Enabled && vvtMode == 2 } field = "VVT2 Cam angle @ 0% duty",vvt2CL0DutyAng, { vvt2Enabled && vvtMode == 2 } - field = "VVT2 Trigger edge", TrigEdgeThrd, { vvt2Enabled && vvtMode == 2 } + dialog = vvtClosedLoop, "Closed loop" field = "Increased duty direction", vvtPWMdir @@ -5518,8 +5519,10 @@ cmdVSSratio6 = "E\x99\x06" ;recordField = Name, HeaderName, startBit, bitCount, scale, units, updateCondition recordField = priLevel, "PriLevel", 0, 1, 1.0, "Flag" recordField = secLevel, "SecLevel", 1, 1, 1.0, "Flag" - recordField = trigger, "Trigger", 2, 1, 1.0, "Flag" - recordField = sync, "Sync", 3, 1, 1.0, "Flag" + recordField = ThirdLevel, "ThirdLevel", 2, 1, 1.0, "Flag" + recordField = trigger, "Trigger", 3, 1, 1.0, "Flag" + recordField = sync, "Sync", 4, 1, 1.0, "Flag" + recordField = cycle, "Cycle", 5, 1, 1.0, "Flag" recordField = refTime, "RefTime", 8, 32, 0.001, "ms" ; hidden calcField serves as intermediate variable @@ -5529,6 +5532,65 @@ cmdVSSratio6 = "E\x99\x06" ;recordField = time, "Time", 24, 16, 1.0, "ms" calcField = time, "Time", "ms", { refTime } +loggerDef = compositeLogger2, "Composite Logger 2nd Cam", composite + startCommand = "O" + stopCommand = "o" + ;dataReadCommand = "T" ; Basic TS command format. Note that this is shared with the composite logger. Firmware detects which log is currently running + dataReadCommand = "T\$tsCanId\x00\x00\x00\x02\x7B" ; Basic TS command format. Note that this is shared with the composite logger. Firmware detects which log is currently running + dataReadTimeout = 50000 ; time in ms + dataReadyCondition = { toothLog1Ready == 1 } + continuousRead = true + dataLength = 127 ; Number of records to show on a single screen. Should match TOOTH_LOG_SIZE in the code + + ;recordDef = headerLen. footerLen, recordLen + recordDef = 0, 0, 5; in bytes, the recordLen is for each record, currently limited to 4 bytes + + ;recordField = Name, HeaderName, startBit, bitCount, scale, units, updateCondition + recordField = priLevel, "PriLevel", 0, 1, 1.0, "Flag" + recordField = secLevel, "SecLevel", 1, 1, 1.0, "Flag" + recordField = ThirdLevel, "ThirdLevel", 2, 1, 1.0, "Flag" + recordField = trigger, "Trigger", 3, 1, 1.0, "Flag" + recordField = sync, "Sync", 4, 1, 1.0, "Flag" + recordField = cycle, "Cycle", 5, 1, 1.0, "Flag" + recordField = refTime, "RefTime", 8, 32, 0.001, "ms" + + ; hidden calcField serves as intermediate variable + calcField = maxTime, "MaxTime", "ms", { maxValue(refTime) }, hidden + + calcField = toothTime, "ToothTime", "ms", { refTime - pastValue(refTime, 1) } + ;recordField = time, "Time", 24, 16, 1.0, "ms" + calcField = time, "Time", "ms", { refTime } + loggerDef = compositeLogger3, "Composite Logger Both cams", composite + startCommand = "X" + stopCommand = "x" + ;dataReadCommand = "T" ; Basic TS command format. Note that this is shared with the composite logger. Firmware detects which log is currently running + dataReadCommand = "T\$tsCanId\x00\x00\x00\x02\x7B" ; Basic TS command format. Note that this is shared with the composite logger. Firmware detects which log is currently running + dataReadTimeout = 50000 ; time in ms + dataReadyCondition = { toothLog1Ready == 1 } + continuousRead = true + dataLength = 127 ; Number of records to show on a single screen. Should match TOOTH_LOG_SIZE in the code + + ;recordDef = headerLen. footerLen, recordLen + recordDef = 0, 0, 5; in bytes, the recordLen is for each record, currently limited to 4 bytes + + ;recordField = Name, HeaderName, startBit, bitCount, scale, units, updateCondition + recordField = priLevel, "PriLevel", 0, 1, 1.0, "Flag" + recordField = secLevel, "SecLevel", 1, 1, 1.0, "Flag" + recordField = ThirdLevel, "ThirdLevel", 2, 1, 1.0, "Flag" + recordField = trigger, "Trigger", 3, 1, 1.0, "Flag" + recordField = sync, "Sync", 4, 1, 1.0, "Flag" + recordField = cycle, "Cycle", 5, 1, 1.0, "Flag" + recordField = refTime, "RefTime", 8, 32, 0.001, "ms" + + ; hidden calcField serves as intermediate variable + calcField = maxTime, "MaxTime", "ms", { maxValue(refTime) }, hidden + + calcField = toothTime, "ToothTime", "ms", { refTime - pastValue(refTime, 1) } + ;recordField = time, "Time", 24, 16, 1.0, "ms" + calcField = time, "Time", "ms", { refTime } + + + [ReferenceTables] tableWriteCommand = "t\$tsCanId%2i%2o%2c%v"; "t%2i%2o%2c%v"; "t\x01\xFC\x00\x01\xFC" "t\%2i%2o%2c%v" #if mcu_stm32 diff --git a/speeduino/comms.cpp b/speeduino/comms.cpp index 0ea61781..726582d4 100644 --- a/speeduino/comms.cpp +++ b/speeduino/comms.cpp @@ -672,6 +672,26 @@ void processSerialCommand(void) break; } + case 'O': //Start the composite logger 2nd cam (teritary) + startCompositeLoggerTertiary(); + sendReturnCodeMsg(SERIAL_RC_OK); + break; + + case 'o': //Stop the composite logger 2nd cam (tertiary) + stopCompositeLoggerTertiary(); + sendReturnCodeMsg(SERIAL_RC_OK); + break; + + case 'X': //Start the composite logger 2nd cam (teritary) + startCompositeLoggerCams(); + sendReturnCodeMsg(SERIAL_RC_OK); + break; + + case 'x': //Stop the composite logger 2nd cam (tertiary) + stopCompositeLoggerCams(); + sendReturnCodeMsg(SERIAL_RC_OK); + break; + /* * New method for sending page values (MS command equivalent is 'r') */ @@ -847,7 +867,7 @@ void processSerialCommand(void) case 'T': //Send 256 tooth log entries to Tuner Studios tooth logger logItemsTransmitted = 0; if(currentStatus.toothLogEnabled == true) { sendToothLog(); } //Sends tooth log values as ints - else if (currentStatus.compositeLogEnabled == true) { sendCompositeLog(); } + else if (currentStatus.compositeTriggerUsed > 0) { sendCompositeLog(); } else { /* MISRA no-op */ } break; diff --git a/speeduino/comms_legacy.cpp b/speeduino/comms_legacy.cpp index 88919041..7f4aaca3 100644 --- a/speeduino/comms_legacy.cpp +++ b/speeduino/comms_legacy.cpp @@ -206,6 +206,24 @@ void legacySerialCommand(void) Serial.println(); break; + case 'O': //Start the composite logger 2nd cam (teritary) + startCompositeLoggerTertiary(); + Serial.write(1); //TS needs an acknowledgement that this was received. I don't know if this is the correct response, but it seems to work + break; + + case 'o': //Stop the composite logger 2nd cam (tertiary) + stopCompositeLoggerTertiary(); + break; + + case 'X': //Start the composite logger 2nd cam (teritary) + startCompositeLoggerCams(); + Serial.write(1); //TS needs an acknowledgement that this was received. I don't know if this is the correct response, but it seems to work + break; + + case 'x': //Stop the composite logger 2nd cam (tertiary) + stopCompositeLoggerCams(); + break; + case 'P': // set the current page //This is a legacy function and is no longer used by TunerStudio. It is maintained for compatibility with other systems //A 2nd byte of data is required after the 'P' specifying the new page number. @@ -320,7 +338,7 @@ void legacySerialCommand(void) Serial.read(); // First byte of the page identifier can be ignored. It's always 0 if(currentStatus.toothLogEnabled == true) { sendToothLog_legacy(0); } //Sends tooth log values as ints - else if (currentStatus.compositeLogEnabled == true) { sendCompositeLog_legacy(0); } + else if (currentStatus.compositeTriggerUsed > 0) { sendCompositeLog_legacy(0); } serialStatusFlag = SERIAL_INACTIVE; } break; diff --git a/speeduino/decoders.h b/speeduino/decoders.h index 2fd6f125..2edd6030 100644 --- a/speeduino/decoders.h +++ b/speeduino/decoders.h @@ -6,9 +6,11 @@ #if defined(CORE_AVR) #define READ_PRI_TRIGGER() ((*triggerPri_pin_port & triggerPri_pin_mask) ? true : false) #define READ_SEC_TRIGGER() ((*triggerSec_pin_port & triggerSec_pin_mask) ? true : false) + #define READ_THIRD_TRIGGER() ((*triggerThird_pin_port & triggerThird_pin_mask) ? true : false) #else #define READ_PRI_TRIGGER() digitalRead(pinTrigger) #define READ_SEC_TRIGGER() digitalRead(pinTrigger2) + #define READ_THIRD_TRIGGER() digitalRead(pinTrigger3) #endif #define DECODER_MISSING_TOOTH 0 @@ -63,6 +65,7 @@ extern bool decoderHasFixedCrankingTiming; void loggerPrimaryISR(void); void loggerSecondaryISR(void); +void loggerTertiaryISR(void); //All of the below are the 6 required functions for each decoder / pattern void triggerSetup_missingTooth(void); @@ -301,7 +304,8 @@ extern int16_t toothAngles[24]; //An array for storing fixed tooth angles. Curre #define CAM_SPEED 1 #define TOOTH_CRANK 0 -#define TOOTH_CAM 1 +#define TOOTH_CAM_SECONDARY 1 +#define TOOTH_CAM_TERTIARY 2 // used by the ROVER MEMS pattern #define ID_TOOTH_PATTERN 0 // have we identified teeth to skip for calculating RPM? diff --git a/speeduino/decoders.ino b/speeduino/decoders.ino index 022e8677..be2aa72f 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -53,6 +53,8 @@ volatile unsigned long curTime; volatile unsigned long curGap; volatile unsigned long curTime2; volatile unsigned long curGap2; +volatile unsigned long curTime3; +volatile unsigned long curGap3; volatile unsigned long lastGap; volatile unsigned long targetGap; @@ -68,6 +70,7 @@ volatile unsigned long toothLastMinusOneSecToothTime = 0; //The time (micros()) volatile unsigned long toothLastToothRisingTime = 0; //The time (micros()) that the last tooth rose (used by special decoders to determine missing teeth polarity) volatile unsigned long toothLastSecToothRisingTime = 0; //The time (micros()) that the last tooth rose on the secondary input (used by special decoders to determine missing teeth polarity) volatile unsigned long targetGap2; +volatile unsigned long targetGap3; volatile unsigned long toothOneTime = 0; //The time (micros()) that tooth 1 last triggered volatile unsigned long toothOneMinusOneTime = 0; //The 2nd to last time (micros()) that tooth 1 last triggered volatile bool revolutionOne = 0; // For sequential operation, this tracks whether the current revolution is 1 or 2 (not 1) @@ -78,9 +81,14 @@ volatile unsigned int secondaryLastToothCount = 0; // used to identify in the ro volatile unsigned long secondaryLastToothTime = 0; //The time (micros()) that the last tooth was registered (Cam input) volatile unsigned long secondaryLastToothTime1 = 0; //The time (micros()) that the last tooth was registered (Cam input) +volatile unsigned int thirdToothCount; //Used for identifying the current third (Usually exhaust cam - used for VVT2) tooth for patterns with multiple secondary teeth +volatile unsigned long thirdLastToothTime = 0; //The time (micros()) that the last tooth was registered (Cam input) +volatile unsigned long thirdLastToothTime1 = 0; //The time (micros()) that the last tooth was registered (Cam input) + uint16_t triggerActualTeeth; volatile unsigned long triggerFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering) volatile unsigned long triggerSecFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering) for the secondary input +volatile unsigned long triggerThirdFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering) for the Third input volatile uint8_t decoderState = 0; @@ -113,15 +121,15 @@ int16_t toothAngles[24]; //An array for storing fixed tooth angles. Currently si // whichTooth - 0 for Primary (Crank), 1 for Secondary (Cam) /** Add tooth log entry to toothHistory (array). - * Enabled by (either) currentStatus.toothLogEnabled and currentStatus.compositeLogEnabled. + * Enabled by (either) currentStatus.toothLogEnabled and currentStatus.compositeTriggerUsed. * @param toothTime - Tooth Time - * @param whichTooth - 0 for Primary (Crank), 1 for Secondary (Cam) + * @param whichTooth - 0 for Primary (Crank), 2 for Secondary (Cam) 3 for Tertiary (Cam) */ -static inline void addToothLogEntry(unsigned long toothTime, bool whichTooth) +static inline void addToothLogEntry(unsigned long toothTime, byte whichTooth) { if(BIT_CHECK(currentStatus.status1, BIT_STATUS1_TOOTHLOG1READY)) { return; } //High speed tooth logging history - if( (currentStatus.toothLogEnabled == true) || (currentStatus.compositeLogEnabled == true) ) + if( (currentStatus.toothLogEnabled == true) || (currentStatus.compositeTriggerUsed > 0) ) { bool valueLogged = false; if(currentStatus.toothLogEnabled == true) @@ -133,14 +141,42 @@ static inline void addToothLogEntry(unsigned long toothTime, bool whichTooth) valueLogged = true; } } - else if(currentStatus.compositeLogEnabled == true) + else if(currentStatus.compositeTriggerUsed > 0) { compositeLogHistory[toothHistoryIndex] = 0; - if(READ_PRI_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_PRI); } - if(READ_SEC_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_SEC); } - if(whichTooth == TOOTH_CAM) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_TRIG); } + if(currentStatus.compositeTriggerUsed == 4) + { + // we want to display both cams so swap the values round to display primary as cam1 and secondary as cam2, include the crank in the data as the third output + if(READ_SEC_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_PRI); } + if(READ_THIRD_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_SEC); } + if(READ_PRI_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_THIRD); } + if(whichTooth > TOOTH_CAM_SECONDARY) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_TRIG); } + } + else + { + // we want to display crank and one of the cams + if(READ_PRI_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_PRI); } + if(currentStatus.compositeTriggerUsed == 3) + { + // display cam2 and also log data for cam 1 + if(READ_THIRD_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_SEC); } // only the COMPOSITE_LOG_SEC value is visualised hence the swapping of the data + if(READ_SEC_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_THIRD); } + } + else + { + // display cam1 and also log data for cam 2 - this is the historic composite view + if(READ_SEC_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_SEC); } + if(READ_THIRD_TRIGGER() == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_THIRD); } + } + if(whichTooth > TOOTH_CRANK) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_TRIG); } + } if(currentStatus.hasSync == true) { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_LOG_SYNC); } + if(revolutionOne == 1) + { BIT_SET(compositeLogHistory[toothHistoryIndex], COMPOSITE_ENGINE_CYCLE);} + else + { BIT_CLEAR(compositeLogHistory[toothHistoryIndex], COMPOSITE_ENGINE_CYCLE);} + toothHistory[toothHistoryIndex] = micros(); valueLogged = true; } @@ -184,7 +220,7 @@ void loggerPrimaryISR(void) addToothLogEntry(curGap, TOOTH_CRANK); } } - else if( (currentStatus.compositeLogEnabled == true) ) + else if( (currentStatus.compositeTriggerUsed > 0) ) { //Composite logger adds an entry regardless of which edge it was addToothLogEntry(curGap, TOOTH_CRANK); @@ -209,13 +245,40 @@ void loggerSecondaryISR(void) triggerSecondaryHandler(); } //No tooth logger for the secondary input - if( (currentStatus.compositeLogEnabled == true) && (BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER)) ) + if( (currentStatus.compositeTriggerUsed > 0) && (BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER)) ) { //Composite logger adds an entry regardless of which edge it was - addToothLogEntry(curGap2, TOOTH_CAM); + addToothLogEntry(curGap2, TOOTH_CAM_SECONDARY); } } +/** Interrupt handler for third trigger. +* As loggerPrimaryISR, but for the third trigger. +*/ +void loggerTertiaryISR(void) +{ + BIT_CLEAR(decoderState, BIT_DECODER_VALID_TRIGGER); //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters + BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters + /* 3 checks here: + 1) If the primary trigger is RISING, then check whether the primary is currently HIGH + 2) If the primary trigger is FALLING, then check whether the primary is currently LOW + 3) The secondary trigger is CHANGING + If any of these are true, the primary decoder function is called + */ + + + if( ( (tertiaryTriggerEdge == RISING) && ( READ_THIRD_TRIGGER() == HIGH) ) || ( (tertiaryTriggerEdge == FALLING) && (READ_THIRD_TRIGGER() == LOW) ) || (tertiaryTriggerEdge == CHANGE) ) + { + triggerTertiaryHandler(); + } + //No tooth logger for the secondary input + if( (currentStatus.compositeTriggerUsed > 0) && (BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER)) ) + { + //Composite logger adds an entry regardless of which edge it was + addToothLogEntry(curGap3, TOOTH_CAM_TERTIARY); + } +} + /** Compute RPM. * As nearly all the decoders use a common method of determining RPM (The time the last full revolution took) A common function is simpler. * @param degreesOver - the number of crank degrees between tooth #1s. Some patterns have a tooth #1 every crank rev, others are every cam rev. @@ -377,6 +440,7 @@ void triggerSetup_missingTooth(void) toothLastMinusOneToothTime = 0; toothCurrentCount = 0; secondaryToothCount = 0; + thirdToothCount = 0; toothOneTime = 0; toothOneMinusOneTime = 0; MAX_STALL_TIME = (3333UL * triggerToothAngle * (configPage4.triggerMissingTeeth + 1)); //Minimum 50rpm. (3333uS is the time per degree at 50rpm) @@ -555,12 +619,29 @@ void triggerThird_missingTooth(void) { //Record the VVT2 Angle (the only purpose of the third trigger) int16_t curAngle; - curAngle = getCrankAngle(); - while(curAngle > 360) { curAngle -= 360; } - curAngle -= configPage4.triggerAngle; //Value at TDC - if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage4.vvt2CL0DutyAng; } - //currentStatus.vvt2Angle = int8_t (curAngle); //vvt1Angle is only int8, but +/-127 degrees is enough for VVT control - currentStatus.vvt2Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt2Angle); + curTime3 = micros(); + curGap3 = curTime3 - toothLastThirdToothTime; + + //Safety check for initial startup + if( (toothLastThirdToothTime == 0) ) + { + curGap3 = 0; + toothLastThirdToothTime = curTime3; + } + + if ( curGap3 >= triggerThirdFilterTime ) + { + thirdToothCount++; + triggerThirdFilterTime = curGap3 >> 1; //Next third filter is 50% the current gap + + curAngle = getCrankAngle(); + while(curAngle > 360) { curAngle -= 360; } + curAngle -= configPage4.triggerAngle; //Value at TDC + if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage4.vvt2CL0DutyAng; } + //currentStatus.vvt2Angle = int8_t (curAngle); //vvt1Angle is only int8, but +/-127 degrees is enough for VVT control + currentStatus.vvt2Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt2Angle); + toothLastThirdToothTime = curTime3; + } // Trigger filter } uint16_t getRPM_missingTooth(void) @@ -1520,7 +1601,7 @@ void triggerSec_4G63(void) { toothLastSecToothTime = curTime2; BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters) - //addToothLogEntry(curGap, TOOTH_CAM); + //addToothLogEntry(curGap, TOOTH_CAM_SECONDARY); triggerSecFilterTime = curGap2 >> 1; //Basic 50% filter for the secondary reading //More aggressive options: diff --git a/speeduino/globals.h b/speeduino/globals.h index 0c21e4c5..8fac1527 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -251,10 +251,13 @@ #define IAT_CALIBRATION_PAGE 1U #define CLT_CALIBRATION_PAGE 0U +// note the sequence of these defines which refernce the bits used in a byte has moved when the third trigger & engine cycle was incorporated #define COMPOSITE_LOG_PRI 0 #define COMPOSITE_LOG_SEC 1 -#define COMPOSITE_LOG_TRIG 2 -#define COMPOSITE_LOG_SYNC 3 +#define COMPOSITE_LOG_THIRD 2 +#define COMPOSITE_LOG_TRIG 3 +#define COMPOSITE_LOG_SYNC 4 +#define COMPOSITE_ENGINE_CYCLE 5 #define EGO_TYPE_OFF 0 #define EGO_TYPE_NARROW 1 @@ -541,6 +544,8 @@ extern volatile PORT_TYPE *triggerPri_pin_port; extern volatile PINMASK_TYPE triggerPri_pin_mask; extern volatile PORT_TYPE *triggerSec_pin_port; extern volatile PINMASK_TYPE triggerSec_pin_mask; +extern volatile PORT_TYPE *triggerThird_pin_port; +extern volatile PINMASK_TYPE triggerThird_pin_mask; extern byte triggerInterrupt; extern byte triggerInterrupt2; @@ -721,7 +726,7 @@ struct statuses { byte knockRetard; bool knockActive; bool toothLogEnabled; - bool compositeLogEnabled; + byte compositeTriggerUsed; // 0 means composite logger disabled, 2 means use secondary input (1st cam), 3 means use tertiary input (2nd cam), 4 means log both cams together int16_t vvt1Angle; //Has to be a long for PID calcs (CL VVT control) byte vvt1TargetAngle; long vvt1Duty; //Has to be a long for PID calcs (CL VVT control) diff --git a/speeduino/globals.ino b/speeduino/globals.ino index d33fdc0e..d8d27998 100644 --- a/speeduino/globals.ino +++ b/speeduino/globals.ino @@ -102,6 +102,8 @@ volatile PORT_TYPE *triggerPri_pin_port; volatile PINMASK_TYPE triggerPri_pin_mask; volatile PORT_TYPE *triggerSec_pin_port; volatile PINMASK_TYPE triggerSec_pin_mask; +volatile PORT_TYPE *triggerThird_pin_port; +volatile PINMASK_TYPE triggerThird_pin_mask; /// These need to be here as they are used in both speeduino.ino and scheduler.ino byte channelInjEnabled = 0; diff --git a/speeduino/init.ino b/speeduino/init.ino index 185b601f..de323a58 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -3001,6 +3001,9 @@ void setPinMapping(byte boardID) triggerPri_pin_mask = digitalPinToBitMask(pinTrigger); triggerSec_pin_port = portInputRegister(digitalPinToPort(pinTrigger2)); triggerSec_pin_mask = digitalPinToBitMask(pinTrigger2); + triggerThird_pin_port = portInputRegister(digitalPinToPort(pinTrigger3)); + triggerThird_pin_mask = digitalPinToBitMask(pinTrigger3); + flex_pin_port = portInputRegister(digitalPinToPort(pinFlex)); flex_pin_mask = digitalPinToBitMask(pinFlex); diff --git a/speeduino/logger.h b/speeduino/logger.h index 6a93e49b..65712589 100644 --- a/speeduino/logger.h +++ b/speeduino/logger.h @@ -35,6 +35,12 @@ void stopToothLogger(void); void startCompositeLogger(void); void stopCompositeLogger(void); +void startCompositeLoggerTertiary(void); +void stopCompositeLoggerTertiary(void); + +void startCompositeLoggerCams(void); +void stopCompositeLoggerCams(void); + // This array indicates which index values from the log are 2 byte values // This array MUST remain in ascending order // !!!! WARNING: If any value above 255 is required in this array, changes MUST be made to is2ByteEntry() function !!!! diff --git a/speeduino/logger.ino b/speeduino/logger.ino index 24015cac..02675081 100644 --- a/speeduino/logger.ino +++ b/speeduino/logger.ino @@ -366,7 +366,7 @@ bool is2ByteEntry(uint8_t key) void startToothLogger(void) { currentStatus.toothLogEnabled = true; - currentStatus.compositeLogEnabled = false; //Safety first (Should never be required) + currentStatus.compositeTriggerUsed = 0; //Safety first (Should never be required) BIT_CLEAR(currentStatus.status1, BIT_STATUS1_TOOTHLOG1READY); toothHistoryIndex = 0; @@ -392,7 +392,7 @@ void stopToothLogger(void) void startCompositeLogger(void) { - currentStatus.compositeLogEnabled = true; + currentStatus.compositeTriggerUsed = 2; currentStatus.toothLogEnabled = false; //Safety first (Should never be required) BIT_CLEAR(currentStatus.status1, BIT_STATUS1_TOOTHLOG1READY); toothHistoryIndex = 0; @@ -407,7 +407,7 @@ void startCompositeLogger(void) void stopCompositeLogger(void) { - currentStatus.compositeLogEnabled = false; + currentStatus.compositeTriggerUsed = 0; //Disconnect the logger interrupts and attach the normal ones detachInterrupt( digitalPinToInterrupt(pinTrigger) ); @@ -416,3 +416,58 @@ void stopCompositeLogger(void) detachInterrupt( digitalPinToInterrupt(pinTrigger2) ); attachInterrupt( digitalPinToInterrupt(pinTrigger2), triggerSecondaryHandler, secondaryTriggerEdge ); } + +void startCompositeLoggerTertiary(void) +{ + currentStatus.compositeTriggerUsed = 3; + currentStatus.toothLogEnabled = false; //Safety first (Should never be required) + BIT_CLEAR(currentStatus.status1, BIT_STATUS1_TOOTHLOG1READY); + toothHistoryIndex = 0; + + //Disconnect the standard interrupt and add the logger version + detachInterrupt( digitalPinToInterrupt(pinTrigger) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger), loggerPrimaryISR, CHANGE ); + + detachInterrupt( digitalPinToInterrupt(pinTrigger3) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger3), loggerTertiaryISR, CHANGE ); +} + +void stopCompositeLoggerTertiary(void) +{ + currentStatus.compositeTriggerUsed = 0; + + //Disconnect the logger interrupts and attach the normal ones + detachInterrupt( digitalPinToInterrupt(pinTrigger) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger), triggerHandler, primaryTriggerEdge ); + + detachInterrupt( digitalPinToInterrupt(pinTrigger3) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger3), triggerTertiaryHandler, tertiaryTriggerEdge ); +} + + +void startCompositeLoggerCams(void) +{ + currentStatus.compositeTriggerUsed = 4; + currentStatus.toothLogEnabled = false; //Safety first (Should never be required) + BIT_CLEAR(currentStatus.status1, BIT_STATUS1_TOOTHLOG1READY); + toothHistoryIndex = 0; + + //Disconnect the standard interrupt and add the logger version + detachInterrupt( digitalPinToInterrupt(pinTrigger2) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger2), loggerSecondaryISR, CHANGE ); + + detachInterrupt( digitalPinToInterrupt(pinTrigger3) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger3), loggerTertiaryISR, CHANGE ); +} + +void stopCompositeLoggerCams(void) +{ + currentStatus.compositeTriggerUsed = false; + + //Disconnect the logger interrupts and attach the normal ones + detachInterrupt( digitalPinToInterrupt(pinTrigger2) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger2), triggerSecondaryHandler, secondaryTriggerEdge ); + + detachInterrupt( digitalPinToInterrupt(pinTrigger3) ); + attachInterrupt( digitalPinToInterrupt(pinTrigger3), triggerTertiaryHandler, tertiaryTriggerEdge ); +} diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index 09745ee9..a0c17c7e 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -188,7 +188,7 @@ void loop(void) //This is a safety check. If for some reason the interrupts have got screwed up (Leading to 0rpm), this resets them. //It can possibly be run much less frequently. //This should only be run if the high speed logger are off because it will change the trigger interrupts back to defaults rather than the logger versions - if( (currentStatus.toothLogEnabled == false) && (currentStatus.compositeLogEnabled == false) ) { initialiseTriggers(); } + if( (currentStatus.toothLogEnabled == false) && (currentStatus.compositeTriggerUsed == 0) ) { initialiseTriggers(); } VVT1_PIN_LOW(); VVT2_PIN_LOW();