diff --git a/DCC.cpp b/DCC.cpp index 972dfa3..96868ca 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -465,15 +465,15 @@ bool DCC::issueReminder(int reg) { break; case 1: // remind function group 1 (F0-F4) if (flags & FN_GROUP_1) - setFunctionInternal(loco,0, 128 | ((functions>>1)& 0x0F) | ((functions & 0x01)<<4)); + setFunctionInternal(loco,0, 128 | ((functions>>1)& 0x0F) | ((functions & 0x01)<<4)); // 100D DDDD break; case 2: // remind function group 2 F5-F8 if (flags & FN_GROUP_2) - setFunctionInternal(loco,0, 176 + ((functions>>5)& 0x0F)); + setFunctionInternal(loco,0, 176 | ((functions>>5)& 0x0F)); // 1011 DDDD break; case 3: // remind function group 3 F9-F12 if (flags & FN_GROUP_3) - setFunctionInternal(loco,0, 160 + ((functions>>9)& 0x0F)); + setFunctionInternal(loco,0, 160 | ((functions>>9)& 0x0F)); // 1010 DDDD break; case 4: // remind function group 4 F13-F20 if (flags & FN_GROUP_4) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 4f4030c..ece2842 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -47,6 +47,7 @@ const int HASH_KEYWORD_DCC = 6436; const int HASH_KEYWORD_SLOW = -17209; const int HASH_KEYWORD_PROGBOOST = -6353; const int HASH_KEYWORD_EEPROM = -7168; +const int HASH_KEYWORD_LIMIT = 27413; int DCCEXParser::stashP[MAX_PARAMS]; bool DCCEXParser::stashBusy; @@ -465,19 +466,19 @@ bool DCCEXParser::parsef(Print *stream, int params, int p[]) // convenient for other processing if (params == 2) { - byte groupcode = p[1] & 0xE0; - if (groupcode == 0x80) + byte instructionField = p[1] & 0xE0; // 1110 0000 + if (instructionField == 0x80) // 1000 0000 Function group 1 { + // Shuffle bits from order F0 F4 F3 F2 F1 to F4 F3 F2 F1 F0 byte normalized = (p[1] << 1 & 0x1e) | (p[1] >> 4 & 0x01); funcmap(p[0], normalized, 0, 4); } - else if (groupcode == 0xC0) + else if (instructionField == 0xA0) // 1010 0000 Function group 2 { - funcmap(p[0], p[1], 5, 8); - } - else if (groupcode == 0xA0) - { - funcmap(p[0], p[1], 9, 12); + if (p[1] & 0x10) // 0001 0000 Bit selects F5toF8 / F9toF12 + funcmap(p[0], p[1], 5, 8); + else + funcmap(p[0], p[1], 9, 12); } } if (params == 3) @@ -586,7 +587,11 @@ bool DCCEXParser::parseD(Print *stream, int params, int p[]) break; case HASH_KEYWORD_ACK: // - Diag::ACK = onOff; + if (params >= 2 && p[1] == HASH_KEYWORD_LIMIT) { + DCCWaveform::progTrack.setAckLimit(p[2]); + StringFormatter::send(stream, F("\nAck limit=%dmA\n"), p[2]); + } else + Diag::ACK = onOff; return true; case HASH_KEYWORD_CMD: // diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index a70ab16..bec16b3 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -128,7 +128,7 @@ void DCCWaveform::checkPowerOverload() { if (millis() - lastSampleTaken < sampleDelay) return; lastSampleTaken = millis(); - int tripValue= motorDriver->rawCurrentTripValue; + int tripValue= motorDriver->getRawCurrentTripValue(); if (!isMainTrack && !ackPending && !progTrackSyncMain && !progTrackBoosted) tripValue=progTripValue; @@ -292,9 +292,12 @@ int DCCWaveform::getLastCurrent() { // (yes I know I could have subclassed the main track but...) void DCCWaveform::setAckBaseline() { - if (isMainTrack) return; - ackThreshold=motorDriver->getCurrentRaw() + (int)(65 / motorDriver->senseFactor); - if (Diag::ACK) DIAG(F("\nACK-BASELINE %d/%dmA"),ackThreshold,motorDriver->raw2mA(ackThreshold)); + if (isMainTrack) return; + int baseline = motorDriver->getCurrentRaw(); + ackThreshold= baseline + motorDriver->mA2raw(ackLimitmA); + if (Diag::ACK) DIAG(F("\nACK baseline=%d/%dmA threshold=%d/%dmA"), + baseline,motorDriver->raw2mA(baseline), + ackThreshold,motorDriver->raw2mA(ackThreshold)); } void DCCWaveform::setAckPending() { diff --git a/DCCWaveform.h b/DCCWaveform.h index d607420..32041e6 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -76,6 +76,9 @@ class DCCWaveform { autoPowerOff=false; } }; + inline void setAckLimit(int mA) { + ackLimitmA = mA; + } private: static VirtualTimer * interruptTimer; @@ -115,9 +118,10 @@ class DCCWaveform { unsigned int power_good_counter = 0; // ACK management (Prog track only) - bool ackPending; - bool ackDetected; + volatile bool ackPending; + volatile bool ackDetected; int ackThreshold; + int ackLimitmA = 60; int ackMaxCurrent; unsigned long ackCheckStart; // millis unsigned int ackCheckDuration; // millis diff --git a/MotorDriver.h b/MotorDriver.h index cce07ad..cbc09cc 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -29,12 +29,16 @@ class MotorDriver { virtual int getCurrentRaw(); virtual unsigned int raw2mA( int raw); virtual int mA2raw( unsigned int mA); - + inline int getRawCurrentTripValue() { + return rawCurrentTripValue; + } + + private: byte powerPin, signalPin, signalPin2, brakePin,currentPin,faultPin; - float senseFactor; - unsigned int tripMilliamps; - int rawCurrentTripValue; - const byte UNUSED_PIN = 255; + float senseFactor; + unsigned int tripMilliamps; + int rawCurrentTripValue; + const byte UNUSED_PIN = 255; }; #endif