mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 18:16:13 +01:00
Compare commits
7 Commits
adb8b56c92
...
36cc46e88d
Author | SHA1 | Date | |
---|---|---|---|
|
36cc46e88d | ||
|
bba74a08f6 | ||
|
ab58c38e7b | ||
|
d4f0a7c8f3 | ||
|
ba0a41b6f2 | ||
|
bf17f2018b | ||
|
67387d2dc3 |
28
DCC.cpp
28
DCC.cpp
|
@ -153,6 +153,21 @@ uint8_t DCC::getThrottleSpeedByte(int cab) {
|
||||||
return speedTable[reg].speedCode;
|
return speedTable[reg].speedCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns 0 to 3 for frequency
|
||||||
|
uint8_t DCC::getThrottleFrequency(int cab) {
|
||||||
|
#if defined(ARDUINO_AVR_UNO)
|
||||||
|
(void)cab;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
int reg=lookupSpeedTable(cab);
|
||||||
|
if (reg<0)
|
||||||
|
return 0; // use default frequency
|
||||||
|
uint8_t res = (uint8_t)(speedTable[reg].functions >>30);
|
||||||
|
DIAG(F("Speed table %d functions %l shifted %d"), reg, speedTable[reg].functions, res);
|
||||||
|
return res; // shift out first 29 bits so we have the "frequency bits" left
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// returns direction on loco
|
// returns direction on loco
|
||||||
// or true/forward on "loco not found"
|
// or true/forward on "loco not found"
|
||||||
bool DCC::getThrottleDirection(int cab) {
|
bool DCC::getThrottleDirection(int cab) {
|
||||||
|
@ -183,22 +198,25 @@ bool DCC::setFn( int cab, int16_t functionNumber, bool on) {
|
||||||
b[nB++] = functionNumber >>7 ; // high order bits
|
b[nB++] = functionNumber >>7 ; // high order bits
|
||||||
}
|
}
|
||||||
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
// We use the reminder table up to 28 for normal functions.
|
||||||
|
// We use 29 to 31 for DC frequency as well.
|
||||||
|
if (functionNumber > 31)
|
||||||
|
return true;
|
||||||
|
|
||||||
int reg = lookupSpeedTable(cab);
|
int reg = lookupSpeedTable(cab);
|
||||||
if (reg<0) return false;
|
if (reg<0) return false;
|
||||||
|
|
||||||
// Take care of functions:
|
// Take care of functions:
|
||||||
// Set state of function
|
// Set state of function
|
||||||
unsigned long previous=speedTable[reg].functions;
|
uint32_t previous=speedTable[reg].functions;
|
||||||
unsigned long funcmask = (1UL<<functionNumber);
|
uint32_t funcmask = (1UL<<functionNumber);
|
||||||
if (on) {
|
if (on) {
|
||||||
speedTable[reg].functions |= funcmask;
|
speedTable[reg].functions |= funcmask;
|
||||||
} else {
|
} else {
|
||||||
speedTable[reg].functions &= ~funcmask;
|
speedTable[reg].functions &= ~funcmask;
|
||||||
}
|
}
|
||||||
if (speedTable[reg].functions != previous) {
|
if (speedTable[reg].functions != previous && functionNumber > 28) {
|
||||||
updateGroupflags(speedTable[reg].groupFlags, functionNumber);
|
updateGroupflags(speedTable[reg].groupFlags, functionNumber);
|
||||||
CommandDistributor::broadcastLoco(reg);
|
CommandDistributor::broadcastLoco(reg);
|
||||||
}
|
}
|
||||||
|
|
3
DCC.h
3
DCC.h
|
@ -61,6 +61,7 @@ public:
|
||||||
static void setThrottle(uint16_t cab, uint8_t tSpeed, bool tDirection);
|
static void setThrottle(uint16_t cab, uint8_t tSpeed, bool tDirection);
|
||||||
static int8_t getThrottleSpeed(int cab);
|
static int8_t getThrottleSpeed(int cab);
|
||||||
static uint8_t getThrottleSpeedByte(int cab);
|
static uint8_t getThrottleSpeedByte(int cab);
|
||||||
|
static uint8_t getThrottleFrequency(int cab);
|
||||||
static bool getThrottleDirection(int cab);
|
static bool getThrottleDirection(int cab);
|
||||||
static void writeCVByteMain(int cab, int cv, byte bValue);
|
static void writeCVByteMain(int cab, int cv, byte bValue);
|
||||||
static void writeCVBitMain(int cab, int cv, byte bNum, bool bValue);
|
static void writeCVBitMain(int cab, int cv, byte bNum, bool bValue);
|
||||||
|
@ -98,7 +99,7 @@ public:
|
||||||
int loco;
|
int loco;
|
||||||
byte speedCode;
|
byte speedCode;
|
||||||
byte groupFlags;
|
byte groupFlags;
|
||||||
unsigned long functions;
|
uint32_t functions;
|
||||||
};
|
};
|
||||||
static LOCO speedTable[MAX_LOCOS];
|
static LOCO speedTable[MAX_LOCOS];
|
||||||
static int lookupSpeedTable(int locoId, bool autoCreate=true);
|
static int lookupSpeedTable(int locoId, bool autoCreate=true);
|
||||||
|
|
|
@ -625,12 +625,13 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
DCC::setThrottle(0,1,1); // this broadcasts speed 1(estop) and sets all reminders to speed 1.
|
DCC::setThrottle(0,1,1); // this broadcasts speed 1(estop) and sets all reminders to speed 1.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef HAVE_ENOUGH_MEMORY
|
||||||
case 'c': // SEND METER RESPONSES <c>
|
case 'c': // SEND METER RESPONSES <c>
|
||||||
// No longer useful because of multiple tracks See <JG> and <JI>
|
// No longer useful because of multiple tracks See <JG> and <JI>
|
||||||
if (params>0) break;
|
if (params>0) break;
|
||||||
TrackManager::reportObsoleteCurrent(stream);
|
TrackManager::reportObsoleteCurrent(stream);
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
case 'Q': // SENSORS <Q>
|
case 'Q': // SENSORS <Q>
|
||||||
Sensor::printAll(stream);
|
Sensor::printAll(stream);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -142,9 +142,9 @@ void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t fbits) {
|
||||||
if (pin == 9 || pin == 10) { // timer 2 is different
|
if (pin == 9 || pin == 10) { // timer 2 is different
|
||||||
|
|
||||||
if (fbits >= 3)
|
if (fbits >= 3)
|
||||||
abits = B11;
|
abits = B00000011;
|
||||||
else
|
else
|
||||||
abits = B01;
|
abits = B00000001;
|
||||||
|
|
||||||
if (fbits >= 3)
|
if (fbits >= 3)
|
||||||
bbits = B0001;
|
bbits = B0001;
|
||||||
|
|
|
@ -125,6 +125,11 @@ void DCCTimer::reset() {
|
||||||
while(true){}
|
while(true){}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) {
|
||||||
|
}
|
||||||
|
void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t fbits) {
|
||||||
|
}
|
||||||
|
|
||||||
int16_t ADCee::ADCmax() {
|
int16_t ADCee::ADCmax() {
|
||||||
return 4095;
|
return 4095;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,11 @@ void DCCTimer::reset() {
|
||||||
while(true) {};
|
while(true) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) {
|
||||||
|
}
|
||||||
|
void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t fbits) {
|
||||||
|
}
|
||||||
|
|
||||||
#define NUM_ADC_INPUTS NUM_ANALOG_INPUTS
|
#define NUM_ADC_INPUTS NUM_ANALOG_INPUTS
|
||||||
|
|
||||||
uint16_t ADCee::usedpins = 0;
|
uint16_t ADCee::usedpins = 0;
|
||||||
|
|
|
@ -141,6 +141,11 @@ void DCCTimer::reset() {
|
||||||
SCB_AIRCR = 0x05FA0004;
|
SCB_AIRCR = 0x05FA0004;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) {
|
||||||
|
}
|
||||||
|
void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t fbits) {
|
||||||
|
}
|
||||||
|
|
||||||
int16_t ADCee::ADCmax() {
|
int16_t ADCee::ADCmax() {
|
||||||
return 4095;
|
return 4095;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define GITHUB_SHA "devel-202312251647Z"
|
#define GITHUB_SHA "devel-202312310824Z"
|
||||||
|
|
|
@ -325,7 +325,7 @@ uint16_t taurustones[28] = { 165, 175, 196, 220,
|
||||||
220, 196, 175, 165 };
|
220, 196, 175, 165 };
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void MotorDriver::setDCSignal(byte speedcode) {
|
void MotorDriver::setDCSignal(byte speedcode, uint8_t frequency /*default =0*/) {
|
||||||
if (brakePin == UNUSED_PIN)
|
if (brakePin == UNUSED_PIN)
|
||||||
return;
|
return;
|
||||||
// spedcoode is a dcc speed & direction
|
// spedcoode is a dcc speed & direction
|
||||||
|
@ -341,7 +341,7 @@ void MotorDriver::setDCSignal(byte speedcode) {
|
||||||
|
|
||||||
{ // new block because of variable f
|
{ // new block because of variable f
|
||||||
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32)
|
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32)
|
||||||
int f = 131;
|
int f = frequency;
|
||||||
#ifdef VARIABLE_TONES
|
#ifdef VARIABLE_TONES
|
||||||
if (tSpeed > 2) {
|
if (tSpeed > 2) {
|
||||||
if (tSpeed <= 58) {
|
if (tSpeed <= 58) {
|
||||||
|
@ -349,10 +349,11 @@ void MotorDriver::setDCSignal(byte speedcode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
DIAG(F("Brake %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 to 100Hz XXX May move to setup
|
||||||
DCCTimer::DCCEXanalogWrite(brakePin,brake);
|
DCCTimer::DCCEXanalogWrite(brakePin,brake);
|
||||||
#else // all AVR here
|
#else // all AVR here
|
||||||
DCCTimer::DCCEXanalogWriteFrequency(brakePin, 0); // 0 is lowest possible f, like 120Hz
|
DCCTimer::DCCEXanalogWriteFrequency(brakePin, frequency); // frequency steps 0 to 3
|
||||||
analogWrite(brakePin,brake);
|
analogWrite(brakePin,brake);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -422,7 +423,7 @@ void MotorDriver::throttleInrush(bool on) {
|
||||||
} else {
|
} else {
|
||||||
pinMode(brakePin, OUTPUT);
|
pinMode(brakePin, OUTPUT);
|
||||||
}
|
}
|
||||||
#else
|
#else // all AVR here
|
||||||
if(on){
|
if(on){
|
||||||
DCCTimer::DCCEXanalogWriteFrequency(brakePin, 3);
|
DCCTimer::DCCEXanalogWriteFrequency(brakePin, 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ class MotorDriver {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); };
|
inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); };
|
||||||
void setDCSignal(byte speedByte);
|
void setDCSignal(byte speedByte, uint8_t frequency=0);
|
||||||
void throttleInrush(bool on);
|
void throttleInrush(bool on);
|
||||||
inline void detachDCSignal() {
|
inline void detachDCSignal() {
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
|
|
|
@ -202,7 +202,7 @@ void TrackManager::setDCSignal(int16_t cab, byte speedbyte) {
|
||||||
FOR_EACH_TRACK(t) {
|
FOR_EACH_TRACK(t) {
|
||||||
if (trackDCAddr[t]!=cab && cab != 0) continue;
|
if (trackDCAddr[t]!=cab && cab != 0) continue;
|
||||||
if (track[t]->getMode() & TRACK_MODE_DC)
|
if (track[t]->getMode() & TRACK_MODE_DC)
|
||||||
track[t]->setDCSignal(speedbyte);
|
track[t]->setDCSignal(speedbyte, DCC::getThrottleFrequency(trackDCAddr[t]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,8 +348,8 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackManager::applyDCSpeed(byte t) {
|
void TrackManager::applyDCSpeed(byte t) {
|
||||||
uint8_t speedByte=DCC::getThrottleSpeedByte(trackDCAddr[t]);
|
track[t]->setDCSignal(DCC::getThrottleSpeedByte(trackDCAddr[t]),
|
||||||
track[t]->setDCSignal(speedByte);
|
DCC::getThrottleFrequency(trackDCAddr[t]));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrackManager::parseEqualSign(Print *stream, int16_t params, int16_t p[])
|
bool TrackManager::parseEqualSign(Print *stream, int16_t params, int16_t p[])
|
||||||
|
@ -574,14 +574,15 @@ bool TrackManager::getPower(byte t, char s[]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TrackManager::reportObsoleteCurrent(Print* stream) {
|
void TrackManager::reportObsoleteCurrent(Print* stream) {
|
||||||
// This function is for backward JMRI compatibility only
|
// This function is for backward JMRI compatibility only
|
||||||
// It reports the first track only, as main, regardless of track settings.
|
// It reports the first track only, as main, regardless of track settings.
|
||||||
// <c MeterName value C/V unit min max res warn>
|
// <c MeterName value C/V unit min max res warn>
|
||||||
|
#ifdef HAVE_ENOUGH_MEMORY
|
||||||
int maxCurrent=track[0]->raw2mA(track[0]->getRawCurrentTripValue());
|
int maxCurrent=track[0]->raw2mA(track[0]->getRawCurrentTripValue());
|
||||||
StringFormatter::send(stream, F("<c CurrentMAIN %d C Milli 0 %d 1 %d>\n"),
|
StringFormatter::send(stream, F("<c CurrentMAIN %d C Milli 0 %d 1 %d>\n"),
|
||||||
track[0]->raw2mA(track[0]->getCurrentRaw(false)), maxCurrent, maxCurrent);
|
track[0]->raw2mA(track[0]->getCurrentRaw(false)), maxCurrent, maxCurrent);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackManager::reportCurrent(Print* stream) {
|
void TrackManager::reportCurrent(Print* stream) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user