1
0
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:
Harald Barth 2021-11-28 23:36:47 +01:00
parent 0e5c89df23
commit 0fbfb5945f
6 changed files with 98 additions and 51 deletions

18
DCC.cpp
View File

@ -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) {

View File

@ -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;

View File

@ -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:

View File

@ -49,18 +49,26 @@ uint8_t DCCWaveform::trailingEdgeCounter=0;
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) { void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
if(mainDriver) {
mainTrack.motorDriver=mainDriver; mainTrack.motorDriver=mainDriver;
mainTrack.setPowerMode(POWERMODE::OFF);
}
if(progDriver) {
progTrack.motorDriver=progDriver; progTrack.motorDriver=progDriver;
progTripValue = progDriver->mA2raw(TRIP_CURRENT_PROG); // need only calculate once hence static progTripValue = progDriver->mA2raw(TRIP_CURRENT_PROG); // need only calculate once hence static
mainTrack.setPowerMode(POWERMODE::OFF);
progTrack.setPowerMode(POWERMODE::OFF); progTrack.setPowerMode(POWERMODE::OFF);
}
if(mainDriver && progDriver) {
// Fault pin config for odd motor boards (example pololu) // Fault pin config for odd motor boards (example pololu)
MotorDriver::commonFaultPin = ((mainDriver->getFaultPin() == progDriver->getFaultPin()) MotorDriver::commonFaultPin = ((mainDriver->getFaultPin() == progDriver->getFaultPin())
&& (mainDriver->getFaultPin() != UNUSED_PIN)); && (mainDriver->getFaultPin() != UNUSED_PIN));
// Only use PWM if both pins are PWM capable. Otherwise JOIN does not work // Only use PWM if both pins are PWM capable. Otherwise JOIN does not work
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable(); MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
}
if(mainDriver || progDriver) {
DIAG(F("Signal pin config: %S accuracy waveform"), 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);
} }

View File

@ -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;
} }

View File

@ -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