diff --git a/DCC.cpp b/DCC.cpp index dbc72e3..95464af 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -153,7 +153,7 @@ uint8_t DCC::getThrottleSpeedByte(int cab) { return speedTable[reg].speedCode; } -// returns 0 to 3 for frequency +// returns 0 to 7 for frequency uint8_t DCC::getThrottleFrequency(int cab) { #if defined(ARDUINO_AVR_UNO) (void)cab; @@ -161,10 +161,11 @@ uint8_t DCC::getThrottleFrequency(int cab) { #else int reg=lookupSpeedTable(cab); if (reg<0) - return 0; // use default frequency - uint8_t res = (uint8_t)(speedTable[reg].functions >>30); + return 0; // use default frequency + // shift out first 29 bits so we have the 3 "frequency bits" left + uint8_t res = (uint8_t)(speedTable[reg].functions >>29); //DIAG(F("Speed table %d functions %l shifted %d"), reg, speedTable[reg].functions, res); - return res; // shift out first 30 bits so we have the "frequency bits" left + return res; #endif } @@ -200,7 +201,9 @@ bool DCC::setFn( int cab, int16_t functionNumber, bool on) { DCCWaveform::mainTrack.schedulePacket(b, nB, 4); } // We use the reminder table up to 28 for normal functions. - // We use 29 to 31 for DC frequency as well. + // We use 29 to 31 for DC frequency as well so up to 28 + // are "real" functions and 29 to 31 are frequency bits + // controlled by function buttons if (functionNumber > 31) return true; diff --git a/DCCTimerAVR.cpp b/DCCTimerAVR.cpp index 5c361a0..3bb2b9f 100644 --- a/DCCTimerAVR.cpp +++ b/DCCTimerAVR.cpp @@ -137,22 +137,27 @@ void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t fbits) { // We are most likely not on pin 3 or 11 as no known motor shield has that as brake. #endif #if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) + // Speed mapping is done like this: + // No functions buttons: 000 0 -> low 131Hz + // Only F29 pressed 001 1 -> mid 490Hz + // F30 with or w/o F29 01x 2-3 -> high 3400Hz + // F31 with or w/o F29/30 1xx 4-7 -> supersonic 62500Hz uint8_t abits; uint8_t bbits; if (pin == 9 || pin == 10) { // timer 2 is different - if (fbits >= 3) + if (fbits >= 4) abits = B00000011; else abits = B00000001; - if (fbits >= 3) + if (fbits >= 4) bbits = B0001; - else if (fbits == 2) + else if (fbits >= 2) bbits = B0010; else if (fbits == 1) bbits = B0100; - else + else // fbits == 0 bbits = B0110; TCCR2A = (TCCR2A & B11111100) | abits; // set WGM0 and WGM1 @@ -162,9 +167,9 @@ void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t fbits) { } else { // not timer 9 or 10 abits = B01; - if (fbits >= 3) + if (fbits >= 4) bbits = B1001; - else if (fbits == 2) + else if (fbits >= 2) bbits = B0010; else if (fbits == 1) bbits = B0011; diff --git a/DCCTimerESP.cpp b/DCCTimerESP.cpp index dbd4e9d..ae81c74 100644 --- a/DCCTimerESP.cpp +++ b/DCCTimerESP.cpp @@ -154,9 +154,13 @@ void DCCTimer::reset() { void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) { if (f >= 16) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, f); - else if (f >= 3) + else if (f == 7) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 62500); - else if (f == 2) + else if (f >= 4) + DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 32000); + else if (f >= 3) + DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 16000); + else if (f >= 2) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 3400); else if (f == 1) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 480); diff --git a/DCCTimerSTM32.cpp b/DCCTimerSTM32.cpp index c220620..19f97b9 100644 --- a/DCCTimerSTM32.cpp +++ b/DCCTimerSTM32.cpp @@ -260,9 +260,13 @@ void DCCTimer::reset() { void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) { if (f >= 16) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, f); - else if (f >= 3) + else if (f == 7) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 62500); - else if (f == 2) + else if (f >= 4) + DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 32000); + else if (f >= 3) + DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 16000); + else if (f >= 2) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 3400); else if (f == 1) DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 480); diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index de254a6..d4537d2 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -679,27 +679,29 @@ void RMFT2::loop2() { } break; case 1: - //if (loco) DCC::setFn(loco,29,true); if (loco) { - DCC::setFn(loco,30,true); + DCC::setFn(loco,29,true); + DCC::setFn(loco,30,false); DCC::setFn(loco,31,false); } break; case 2: - //if (loco) DCC::setFn(loco,30,true); if (loco) { + DCC::setFn(loco,29,false); + DCC::setFn(loco,30,true); + DCC::setFn(loco,31,false); + } + break; + case 3: + if (loco) { + DCC::setFn(loco,29,false); DCC::setFn(loco,30,false); DCC::setFn(loco,31,true); } break; - case 3: - //if (loco) DCC::setFn(loco,31,true); - if (loco) { - DCC::setFn(loco,30,true); - DCC::setFn(loco,31,true); - } - break; - + default: + ; // do nothing + break; } break; diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 3c207f2..09e2c58 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -350,10 +350,10 @@ void MotorDriver::setDCSignal(byte speedcode, uint8_t frequency /*default =0*/) } #endif //DIAG(F("Brake pin %d freqency %d"), brakePin, f); - DCCTimer::DCCEXanalogWriteFrequency(brakePin, f); // set DC PWM frequency to 100Hz XXX May move to setup + DCCTimer::DCCEXanalogWriteFrequency(brakePin, f); // set DC PWM frequency DCCTimer::DCCEXanalogWrite(brakePin,brake); #else // all AVR here - DCCTimer::DCCEXanalogWriteFrequency(brakePin, frequency); // frequency steps 0 to 3 + DCCTimer::DCCEXanalogWriteFrequency(brakePin, frequency); // frequency steps analogWrite(brakePin,brake); #endif } @@ -406,26 +406,26 @@ void MotorDriver::throttleInrush(bool on) { return; if ( !(trackMode & (TRACK_MODE_MAIN | TRACK_MODE_PROG | TRACK_MODE_EXT))) return; - byte duty = on ? 208 : 0; + byte duty = on ? 207 : 0; // duty of 81% at 62500Hz this gives pauses of 3usec if (invertBrake) duty = 255-duty; #if defined(ARDUINO_ARCH_ESP32) if(on) { DCCTimer::DCCEXanalogWrite(brakePin,duty); - DCCTimer::DCCEXanalogWriteFrequency(brakePin, 62500); + DCCTimer::DCCEXanalogWriteFrequency(brakePin, 7); // 7 means max } else { ledcDetachPin(brakePin); } #elif defined(ARDUINO_ARCH_STM32) if(on) { - DCCTimer::DCCEXanalogWriteFrequency(brakePin, 62500); + DCCTimer::DCCEXanalogWriteFrequency(brakePin, 7); // 7 means max DCCTimer::DCCEXanalogWrite(brakePin,duty); } else { pinMode(brakePin, OUTPUT); } #else // all AVR here if(on){ - DCCTimer::DCCEXanalogWriteFrequency(brakePin, 3); + DCCTimer::DCCEXanalogWriteFrequency(brakePin, 7); // 7 means max } analogWrite(brakePin,duty); #endif