mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 21:01:25 +01:00
MotorDriverContainer (multi-motordriver) start
This commit is contained in:
parent
2632d44ec9
commit
f7e90e7b73
@ -85,11 +85,7 @@ void setup()
|
||||
#endif // ETHERNET_ON
|
||||
|
||||
// Responsibility 3: Start the DCC engine.
|
||||
// Note: this provides DCC with two motor drivers, main and prog, which handle the motor shield(s)
|
||||
// Standard supported devices have pre-configured macros but custome hardware installations require
|
||||
// detailed pin mappings and may also require modified subclasses of the MotorDriver to implement specialist logic.
|
||||
// STANDARD_MOTOR_SHIELD, POLOLU_MOTOR_SHIELD, FIREBOX_MK1, FIREBOX_MK1S are pre defined in MotorShields.h
|
||||
DCC::begin(MOTOR_SHIELD_TYPE);
|
||||
DCC::begin();
|
||||
|
||||
// Start RMFT (ignored if no automnation)
|
||||
RMFT::begin();
|
||||
|
10
DCC.cpp
10
DCC.cpp
@ -26,6 +26,9 @@
|
||||
#include "FSH.h"
|
||||
#include "IODevice.h"
|
||||
|
||||
#include "MotorDriver.h"
|
||||
extern MotorDriverContainer mDC;
|
||||
|
||||
// This module is responsible for converting API calls into
|
||||
// messages to be sent to the waveform generator.
|
||||
// It has no visibility of the hardware, timers, interrupts
|
||||
@ -49,9 +52,8 @@ FSH* DCC::shieldName=NULL;
|
||||
byte DCC::joinRelay=UNUSED_PIN;
|
||||
byte DCC::globalSpeedsteps=128;
|
||||
|
||||
void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriver* progDriver) {
|
||||
shieldName=(FSH *)motorShieldName;
|
||||
StringFormatter::send(Serial,F("<iDCC-EX V-%S / %S / %S G-%S>\n"), F(VERSION), F(ARDUINO_TYPE), shieldName, F(GITHUB_SHA));
|
||||
void DCC::begin() {
|
||||
StringFormatter::send(Serial,F("<iDCC-EX V-%S / %S / %S G-%S>\n"), F(VERSION), F(ARDUINO_TYPE), mDC.getMotorShieldName(), F(GITHUB_SHA));
|
||||
|
||||
// Initialise HAL layer before reading EEprom.
|
||||
IODevice::begin();
|
||||
@ -60,7 +62,7 @@ void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriv
|
||||
(void)EEPROM; // tell compiler not to warn this is unused
|
||||
EEStore::init();
|
||||
|
||||
DCCWaveform::begin(mainDriver,progDriver);
|
||||
DCCWaveform::begin(mDC.mainTrack(),mDC.progTrack());
|
||||
}
|
||||
|
||||
void DCC::setJoinRelayPin(byte joinRelayPin) {
|
||||
|
2
DCC.h
2
DCC.h
@ -77,7 +77,7 @@ const byte MAX_LOCOS = 50;
|
||||
class DCC
|
||||
{
|
||||
public:
|
||||
static void begin(const FSH * motorShieldName, MotorDriver *mainDriver, MotorDriver *progDriver);
|
||||
static void begin();
|
||||
static void setJoinRelayPin(byte joinRelayPin);
|
||||
static void loop();
|
||||
|
||||
|
@ -92,8 +92,10 @@ void IRAM_ATTR DCCWaveform::interruptHandler() {
|
||||
byte sigMain=signalTransform[mainTrack.state];
|
||||
byte sigProg=progTrackSyncMain? sigMain : signalTransform[progTrack.state];
|
||||
// Set the signal state for both tracks
|
||||
mainTrack.motorDriver->setSignal(sigMain);
|
||||
progTrack.motorDriver->setSignal(sigProg);
|
||||
if (mainTrack.motorDriver)
|
||||
mainTrack.motorDriver->setSignal(sigMain);
|
||||
if (progTrack.motorDriver)
|
||||
progTrack.motorDriver->setSignal(sigProg);
|
||||
// Move on in the state engine
|
||||
mainTrack.state=stateTransform[mainTrack.state];
|
||||
progTrack.state=stateTransform[progTrack.state];
|
||||
@ -148,12 +150,14 @@ POWERMODE DCCWaveform::getPowerMode() {
|
||||
void DCCWaveform::setPowerMode(POWERMODE mode) {
|
||||
powerMode = mode;
|
||||
bool ison = (mode == POWERMODE::ON);
|
||||
motorDriver->setPower( ison);
|
||||
if (motorDriver)
|
||||
motorDriver->setPower( ison);
|
||||
sentResetsSincePacket=0;
|
||||
}
|
||||
|
||||
|
||||
void DCCWaveform::checkPowerOverload(bool ackManagerActive) {
|
||||
if (!motorDriver) return;
|
||||
if (millis() - lastSampleTaken < sampleDelay) return;
|
||||
lastSampleTaken = millis();
|
||||
int tripValue= motorDriver->getRawCurrentTripValue();
|
||||
@ -323,6 +327,7 @@ void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repea
|
||||
// (yes I know I could have subclassed the main track but...)
|
||||
|
||||
void DCCWaveform::setAckBaseline() {
|
||||
if (!motorDriver) return;
|
||||
if (isMainTrack) return;
|
||||
int baseline=motorDriver->getCurrentRaw();
|
||||
ackThreshold= baseline + motorDriver->mA2raw(ackLimitmA);
|
||||
@ -345,6 +350,7 @@ void DCCWaveform::setAckPending() {
|
||||
}
|
||||
|
||||
byte DCCWaveform::getAck() {
|
||||
if (!motorDriver) return 0;
|
||||
if (ackPending) return (2); // still waiting
|
||||
if (Diag::ACK) DIAG(F("%S after %dmS max=%d/%dmA pulse=%duS samples=%d gaps=%d"),ackDetected?F("ACK"):F("NO-ACK"), ackCheckDuration,
|
||||
ackMaxCurrent,motorDriver->raw2mA(ackMaxCurrent), ackPulseDuration, numAckSamples, numAckGaps);
|
||||
@ -355,6 +361,7 @@ byte DCCWaveform::getAck() {
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("-O3")
|
||||
void IRAM_ATTR DCCWaveform::checkAck() {
|
||||
if (!motorDriver) return;
|
||||
// This function operates in interrupt() time so must be fast and can't DIAG
|
||||
if (sentResetsSincePacket > 6) { //ACK timeout
|
||||
ackCheckDuration=millis()-ackCheckStart;
|
||||
|
@ -17,6 +17,8 @@
|
||||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
#include "MotorDriver.h"
|
||||
#include "DCCTimer.h"
|
||||
#include "DIAG.h"
|
||||
@ -194,3 +196,25 @@ void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & res
|
||||
result.maskLOW = ~result.maskHIGH;
|
||||
// DIAG(F(" port=0x%x, inoutpin=0x%x, isinput=%d, mask=0x%x"),port, result.inout,input,result.maskHIGH);
|
||||
}
|
||||
|
||||
MotorDriverContainer::MotorDriverContainer(const FSH * motorShieldName,
|
||||
MotorDriver *m0,
|
||||
MotorDriver *m1,
|
||||
MotorDriver *m2,
|
||||
MotorDriver *m3,
|
||||
MotorDriver *m4,
|
||||
MotorDriver *m5,
|
||||
MotorDriver *m6,
|
||||
MotorDriver *m7) {
|
||||
mD[0]=m0;
|
||||
mD[1]=m1;
|
||||
mD[2]=m2;
|
||||
mD[3]=m3;
|
||||
mD[4]=m4;
|
||||
mD[5]=m5;
|
||||
mD[6]=m6;
|
||||
mD[7]=m7;
|
||||
shieldName = (FSH *)motorShieldName;
|
||||
}
|
||||
|
||||
MotorDriverContainer mDC(MOTOR_SHIELD_TYPE);
|
||||
|
@ -106,4 +106,25 @@ class MotorDriver {
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class MotorDriverContainer {
|
||||
public:
|
||||
MotorDriverContainer(const FSH * motorShieldName,
|
||||
MotorDriver *m0=NULL,
|
||||
MotorDriver *m1=NULL,
|
||||
MotorDriver *m2=NULL,
|
||||
MotorDriver *m3=NULL,
|
||||
MotorDriver *m4=NULL,
|
||||
MotorDriver *m5=NULL,
|
||||
MotorDriver *m6=NULL,
|
||||
MotorDriver *m7=NULL);
|
||||
// void SetCapability(byte n, byte cap, char [] name);
|
||||
inline FSH *getMotorShieldName() { return shieldName; };
|
||||
inline MotorDriver *mainTrack() { return mD[0]; }; //start fixed
|
||||
inline MotorDriver *progTrack() { return mD[1]; };
|
||||
|
||||
private:
|
||||
MotorDriver *mD[8];
|
||||
FSH *shieldName;
|
||||
};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user