mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-26 17:46:14 +01:00
make mDC a vector in the Container and bugfixes
This commit is contained in:
parent
0e5c89df23
commit
0fbfb5945f
18
DCC.cpp
18
DCC.cpp
|
@ -56,24 +56,26 @@ void DCC::begin() {
|
||||||
StringFormatter::send(Serial,F("<iDCC-EX V-%S / %S / %S G-%S>\n"), F(VERSION), F(ARDUINO_TYPE),
|
StringFormatter::send(Serial,F("<iDCC-EX V-%S / %S / %S G-%S>\n"), F(VERSION), F(ARDUINO_TYPE),
|
||||||
MotorDriverContainer::mDC.getMotorShieldName(), F(GITHUB_SHA));
|
MotorDriverContainer::mDC.getMotorShieldName(), F(GITHUB_SHA));
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOT YES, PIN CONFLICTS
|
||||||
// Initialise HAL layer before reading EEprom.
|
// Initialise HAL layer before reading EEprom.
|
||||||
IODevice::begin();
|
IODevice::begin();
|
||||||
|
*/
|
||||||
|
//MotorDriverContainer::mDC.add(new MotorDriver(16, 21, UNUSED_PIN, UNUSED_PIN, UNUSED_PIN, 2.00, 2000, UNUSED_PIN, RMT_MAIN));
|
||||||
|
|
||||||
// Load stuff from EEprom
|
// Load stuff from EEprom
|
||||||
(void)EEPROM; // tell compiler not to warn this is unused
|
(void)EEPROM; // tell compiler not to warn this is unused
|
||||||
EEStore::init();
|
EEStore::init();
|
||||||
|
|
||||||
|
MotorDriverContainer::mDC.diag();
|
||||||
DCCWaveform::begin(MotorDriverContainer::mDC.mainTrack(),MotorDriverContainer::mDC.progTrack());
|
DCCWaveform::begin(MotorDriverContainer::mDC.mainTrack(),MotorDriverContainer::mDC.progTrack());
|
||||||
DCCTrack::mainTrack.addDriver(MotorDriverContainer::mDC.mainTrack());
|
|
||||||
DCCTrack::progTrack.addDriver(MotorDriverContainer::mDC.progTrack());
|
|
||||||
|
|
||||||
MotorDriver *md;
|
// Add main and prog drivers to the main and prog packet sources (dcc-tracks).
|
||||||
MotorDriverContainer::mDC.add(2, md = new MotorDriver(16, 21, UNUSED_PIN, UNUSED_PIN, UNUSED_PIN, 2.00, 2000, UNUSED_PIN, RMT_MAIN));
|
std::vector<MotorDriver*> v;
|
||||||
DCCTrack::mainTrack.addDriver(md);
|
v = MotorDriverContainer::mDC.getDriverType(RMT_MAIN|TIMER_MAIN);
|
||||||
/*
|
|
||||||
std::vector<MotorDriver*> v = MotorDriverContainer::mDC.getDriverType(RMT_MAIN);
|
|
||||||
for (const auto& d: v) DCCTrack::mainTrack.addDriver(d);
|
for (const auto& d: v) DCCTrack::mainTrack.addDriver(d);
|
||||||
*/
|
v = MotorDriverContainer::mDC.getDriverType(RMT_PROG|TIMER_PROG);
|
||||||
|
for (const auto& d: v) DCCTrack::progTrack.addDriver(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCC::setJoinRelayPin(byte joinRelayPin) {
|
void DCC::setJoinRelayPin(byte joinRelayPin) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ void DCCTrack::schedulePacket(dccPacket packet) {
|
||||||
//DIAG(F("DCCTrack::schedulePacket RMT l=%d d=%x"),packet.length, packet.data[0]);
|
//DIAG(F("DCCTrack::schedulePacket RMT l=%d d=%x"),packet.length, packet.data[0]);
|
||||||
driver->schedulePacket(packet);
|
driver->schedulePacket(packet);
|
||||||
}
|
}
|
||||||
if (driver->type() == TIMERINTERRUPT && waveform && once) {
|
if (driver->type() & (TIMER_MAIN | TIMER_PROG) && waveform && once) {
|
||||||
//DIAG(F("DCCTrack::schedulePacket WAVE l=%d d=%x"),packet.length, packet.data[0]);
|
//DIAG(F("DCCTrack::schedulePacket WAVE l=%d d=%x"),packet.length, packet.data[0]);
|
||||||
waveform->schedulePacket(packet);
|
waveform->schedulePacket(packet);
|
||||||
once=false;
|
once=false;
|
||||||
|
|
|
@ -3,13 +3,16 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "DCCPacket.h"
|
#include "DCCPacket.h"
|
||||||
#include "DCCWaveform.h"
|
#include "DCCWaveform.h"
|
||||||
|
#include "DIAG.h"
|
||||||
|
|
||||||
class DCCTrack {
|
class DCCTrack {
|
||||||
public:
|
public:
|
||||||
DCCTrack(DCCWaveform *w);
|
DCCTrack(DCCWaveform *w);
|
||||||
void schedulePacket(const byte buffer[], byte byteCount, byte repeats);
|
void schedulePacket(const byte buffer[], byte byteCount, byte repeats);
|
||||||
void schedulePacket(dccPacket packet);
|
void schedulePacket(dccPacket packet);
|
||||||
inline void addDriver(MotorDriver *m) { mD.push_back(m); };
|
inline void addDriver(MotorDriver *m) { mD.push_back(m);
|
||||||
|
DIAG(F("Track: mDType=%d count=%d"),m->type(), mD.size());
|
||||||
|
};
|
||||||
static DCCTrack mainTrack;
|
static DCCTrack mainTrack;
|
||||||
static DCCTrack progTrack;
|
static DCCTrack progTrack;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -49,18 +49,26 @@ uint8_t DCCWaveform::trailingEdgeCounter=0;
|
||||||
|
|
||||||
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
|
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
|
||||||
|
|
||||||
mainTrack.motorDriver=mainDriver;
|
if(mainDriver) {
|
||||||
progTrack.motorDriver=progDriver;
|
mainTrack.motorDriver=mainDriver;
|
||||||
progTripValue = progDriver->mA2raw(TRIP_CURRENT_PROG); // need only calculate once hence static
|
mainTrack.setPowerMode(POWERMODE::OFF);
|
||||||
mainTrack.setPowerMode(POWERMODE::OFF);
|
}
|
||||||
progTrack.setPowerMode(POWERMODE::OFF);
|
if(progDriver) {
|
||||||
// Fault pin config for odd motor boards (example pololu)
|
progTrack.motorDriver=progDriver;
|
||||||
MotorDriver::commonFaultPin = ((mainDriver->getFaultPin() == progDriver->getFaultPin())
|
progTripValue = progDriver->mA2raw(TRIP_CURRENT_PROG); // need only calculate once hence static
|
||||||
&& (mainDriver->getFaultPin() != UNUSED_PIN));
|
progTrack.setPowerMode(POWERMODE::OFF);
|
||||||
// Only use PWM if both pins are PWM capable. Otherwise JOIN does not work
|
}
|
||||||
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
|
if(mainDriver && progDriver) {
|
||||||
DIAG(F("Signal pin config: %S accuracy waveform"),
|
// Fault pin config for odd motor boards (example pololu)
|
||||||
|
MotorDriver::commonFaultPin = ((mainDriver->getFaultPin() == progDriver->getFaultPin())
|
||||||
|
&& (mainDriver->getFaultPin() != UNUSED_PIN));
|
||||||
|
// Only use PWM if both pins are PWM capable. Otherwise JOIN does not work
|
||||||
|
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
|
||||||
|
}
|
||||||
|
if(mainDriver || progDriver) {
|
||||||
|
DIAG(F("Signal pin config: %S accuracy waveform"),
|
||||||
MotorDriver::usePWM ? F("high") : F("normal") );
|
MotorDriver::usePWM ? F("high") : F("normal") );
|
||||||
|
}
|
||||||
DCCTimer::begin(DCCWaveform::interruptHandler);
|
DCCTimer::begin(DCCWaveform::interruptHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8
|
||||||
rmtChannel = new RMTChannel(signalPin, 0, PREAMBLE_BITS_MAIN);
|
rmtChannel = new RMTChannel(signalPin, 0, PREAMBLE_BITS_MAIN);
|
||||||
#endif
|
#endif
|
||||||
dualSignal=false;
|
dualSignal=false;
|
||||||
} else if (dtype == TIMERINTERRUPT) {
|
} else if (dtype & (TIMER_MAIN | TIMER_PROG)) {
|
||||||
signalPin=signal_pin;
|
signalPin=signal_pin;
|
||||||
getFastPin(F("SIG"),signalPin,fastSignalPin);
|
getFastPin(F("SIG"),signalPin,fastSignalPin);
|
||||||
pinMode(signalPin, OUTPUT);
|
pinMode(signalPin, OUTPUT);
|
||||||
|
@ -212,8 +212,9 @@ bool MotorDriver::schedulePacket(dccPacket packet) {
|
||||||
if(!rmtChannel) return true; // fake success if functionality is not there
|
if(!rmtChannel) return true; // fake success if functionality is not there
|
||||||
|
|
||||||
outQueue.push(packet);
|
outQueue.push(packet);
|
||||||
if (outQueue.size() > 10) {
|
uint16_t size = outQueue.size();
|
||||||
DIAG(F("Warning: outQueue > 10"));
|
if (size > 10) {
|
||||||
|
DIAG(F("Warning: outQueue %d > 10"),size);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -232,33 +233,41 @@ MotorDriverContainer::MotorDriverContainer(const FSH * motorShieldName,
|
||||||
MotorDriver *m5,
|
MotorDriver *m5,
|
||||||
MotorDriver *m6,
|
MotorDriver *m6,
|
||||||
MotorDriver *m7) {
|
MotorDriver *m7) {
|
||||||
mD[0]=m0;
|
// THIS AUTOMATIC DOES NOT WORK YET. TIMER_MAIN AND TIMER_PROG required in CONSTRUCTOR
|
||||||
mD[1]=m1;
|
// AND CAN NOT BE ADDED LATER
|
||||||
mD[2]=m2;
|
if (m0) {
|
||||||
mD[3]=m3;
|
if (m0->type() == TYPE_UNKNOWN)
|
||||||
mD[4]=m4;
|
m0->setType(TIMER_MAIN);
|
||||||
mD[5]=m5;
|
mD.push_back(m0);
|
||||||
mD[6]=m6;
|
}
|
||||||
mD[7]=m7;
|
if (m1) {
|
||||||
|
if (m1->type() == TYPE_UNKNOWN)
|
||||||
|
m1->setType(TIMER_PROG);
|
||||||
|
mD.push_back(m1);
|
||||||
|
}
|
||||||
|
if (m2) mD.push_back(m2);
|
||||||
|
if (m3) mD.push_back(m3);
|
||||||
|
if (m4) mD.push_back(m4);
|
||||||
|
if (m5) mD.push_back(m5);
|
||||||
|
if (m6) mD.push_back(m6);
|
||||||
|
if (m7) mD.push_back(m7);
|
||||||
shieldName = (FSH *)motorShieldName;
|
shieldName = (FSH *)motorShieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotorDriverContainer::loop() {
|
void MotorDriverContainer::loop() {
|
||||||
static byte i = 0;
|
|
||||||
|
|
||||||
// loops over MotorDrivers which have loop tasks
|
// loops over MotorDrivers which have loop tasks
|
||||||
if (mD[i])
|
if (mD.empty())
|
||||||
if (mD[i]->type() == RMT_MAIN || mD[i]->type() == RMT_PROG)
|
return;
|
||||||
mD[i]->loop();
|
for(const auto& d: mD)
|
||||||
i++;
|
if (d->type() & (RMT_MAIN | RMT_PROG))
|
||||||
if(i > 7) i=0;
|
d->loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MotorDriver*> MotorDriverContainer::getDriverType(driverType t) {
|
std::vector<MotorDriver*> MotorDriverContainer::getDriverType(driverType t) {
|
||||||
std::vector<MotorDriver*> v;
|
std::vector<MotorDriver*> v;
|
||||||
for(byte i=0; i<8; i++) {
|
for(const auto& d: mD){
|
||||||
if (mD[i] && mD[i]->type() == t)
|
if (d->type() & t)
|
||||||
v.push_back(mD[i]);
|
v.push_back(d);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "FSH.h"
|
#include "FSH.h"
|
||||||
|
#include "DIAG.h"
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -57,13 +58,20 @@ struct FASTPIN {
|
||||||
#define isHIGH(fastpin) (*fastpin.inout & fastpin.maskHIGH)
|
#define isHIGH(fastpin) (*fastpin.inout & fastpin.maskHIGH)
|
||||||
#define isLOW(fastpin) (!isHIGH(fastpin))
|
#define isLOW(fastpin) (!isHIGH(fastpin))
|
||||||
|
|
||||||
enum driverType { TIMERINTERRUPT, RMT_MAIN, RMT_PROG, DC_ENA, DC_BRAKE };
|
typedef byte driverType;
|
||||||
|
const driverType TYPE_UNKNOWN=0;
|
||||||
|
const driverType TIMER_MAIN=1;
|
||||||
|
const driverType TIMER_PROG=2;
|
||||||
|
const driverType RMT_MAIN=4;
|
||||||
|
const driverType RMT_PROG=16;
|
||||||
|
const driverType DC_ENA=32;
|
||||||
|
const driverType DC_BRAKE=64;
|
||||||
|
|
||||||
class MotorDriver {
|
class MotorDriver {
|
||||||
public:
|
public:
|
||||||
MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin,
|
MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin,
|
||||||
byte current_pin, float senseFactor, unsigned int tripMilliamps, byte faultPin,
|
byte current_pin, float senseFactor, unsigned int tripMilliamps, byte faultPin,
|
||||||
driverType t=TIMERINTERRUPT);
|
driverType t=TYPE_UNKNOWN);
|
||||||
void setPower( bool on);
|
void setPower( bool on);
|
||||||
void setSignal( bool high);
|
void setSignal( bool high);
|
||||||
void setBrake( bool on);
|
void setBrake( bool on);
|
||||||
|
@ -83,6 +91,7 @@ class MotorDriver {
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
void loop();
|
void loop();
|
||||||
inline driverType type() { return dtype; };
|
inline driverType type() { return dtype; };
|
||||||
|
inline void setType(driverType t) { dtype = t; };
|
||||||
bool schedulePacket(dccPacket packet);
|
bool schedulePacket(dccPacket packet);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -129,19 +138,35 @@ public:
|
||||||
MotorDriver *m6=NULL,
|
MotorDriver *m6=NULL,
|
||||||
MotorDriver *m7=NULL);
|
MotorDriver *m7=NULL);
|
||||||
static MotorDriverContainer mDC;
|
static MotorDriverContainer mDC;
|
||||||
inline void add(byte n, MotorDriver *m) {
|
inline void add(MotorDriver *m) {
|
||||||
if (n>8) return;
|
mD.push_back(m);
|
||||||
mD[n] = m;
|
DIAG(F("Container: mDType=%d count=%d"),m->type(), mD.size());
|
||||||
};
|
};
|
||||||
// void SetCapability(byte n, byte cap, char [] name);
|
// void SetCapability(byte n, byte cap, char [] name);
|
||||||
inline FSH *getMotorShieldName() { return shieldName; };
|
inline FSH *getMotorShieldName() { return shieldName; };
|
||||||
inline MotorDriver *mainTrack() { return mD[0]; }; //start fixed
|
inline void diag() {
|
||||||
inline MotorDriver *progTrack() { return mD[1]; };
|
if (mD.empty()) {
|
||||||
|
DIAG(F("Container empty"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(const auto& d: mD)
|
||||||
|
DIAG(F("Container: mDType=%d count=%d"),d->type(), mD.size());
|
||||||
|
};
|
||||||
|
inline MotorDriver *mainTrack() {
|
||||||
|
std::vector<MotorDriver *> v = getDriverType(TIMER_MAIN);
|
||||||
|
if(v.empty()) return NULL;
|
||||||
|
return v.front();
|
||||||
|
};
|
||||||
|
inline MotorDriver *progTrack() {
|
||||||
|
std::vector<MotorDriver *> v = getDriverType(TIMER_PROG);
|
||||||
|
if(v.empty()) return NULL;
|
||||||
|
return v.front();
|
||||||
|
};
|
||||||
void loop();
|
void loop();
|
||||||
std::vector<MotorDriver*> getDriverType(driverType t);
|
std::vector<MotorDriver*> getDriverType(driverType t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MotorDriver *mD[8];
|
std::vector<MotorDriver *>mD;
|
||||||
FSH *shieldName;
|
FSH *shieldName;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user