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