From 945af43500623544edde50f3fda6cb3f2a1547da Mon Sep 17 00:00:00 2001 From: Asbelos Date: Tue, 11 May 2021 15:09:44 +0100 Subject: [PATCH] Not working --- DCCTimer.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++---- DCCTimer.h | 1 + DCCWaveform.cpp | 10 +++++++- MotorDriver.cpp | 10 ++++++++ MotorDriver.h | 3 +++ MotorDrivers.h | 5 ++++ 6 files changed, 86 insertions(+), 5 deletions(-) diff --git a/DCCTimer.cpp b/DCCTimer.cpp index 727caa1..7ffa3a5 100644 --- a/DCCTimer.cpp +++ b/DCCTimer.cpp @@ -75,6 +75,11 @@ INTERRUPT_CALLBACK interruptHandler=0; (void) pin; return false; // TODO what are the relevant pins? } + + bool DCCTimer::isPWMPin(byte pin) { + (void) pin; + return false; // TODO what are the relevant pins? + } void DCCTimer::setPWM(byte pin, bool high) { (void) pin; @@ -104,6 +109,12 @@ INTERRUPT_CALLBACK interruptHandler=0; return false; // TODO what are the relevant pins? } + bool DCCTimer::isRailcomPin(byte pin) { + //Teensy: digitalPinHasPWM, todo + (void) pin; + return false; // TODO what are the relevant pins? + } + void DCCTimer::setPWM(byte pin, bool high) { // TODO what are the relevant pins? (void) pin; @@ -152,7 +163,11 @@ void DCCTimer::read(uint8_t word, uint8_t *mac, uint8_t offset) { #define TIMER1_A_PIN 11 #define TIMER1_B_PIN 12 #define TIMER1_C_PIN 13 -#else + //railcom timer facility + // #define TIMER4_A_PIN 6 + #define TIMER4_B_PIN 7 + #define TIMER4_C_PIN 8 + #else #define TIMER1_A_PIN 9 #define TIMER1_B_PIN 10 #endif @@ -166,6 +181,16 @@ void DCCTimer::read(uint8_t word, uint8_t *mac, uint8_t offset) { TCNT1 = 0; TCCR1B = _BV(WGM13) | _BV(CS10); // Mode 8, clock select 1 TIMSK1 = _BV(TOIE1); // Enable Software interrupt + + #if defined(TIMER4_A_PIN) + //railcom timer facility + TCCR4A = 0; + ICR4 = CLOCK_CYCLES; + TCNT4 = CLOCK_CYCLES/2; // this timer fires half cycle after Timer 1 + TCCR4B = _BV(WGM13) | _BV(CS10); // Mode 8, clock select 1 + TIMSK4 = 0; // Disable Software interrupt + #endif + interrupts(); } @@ -181,20 +206,49 @@ void DCCTimer::read(uint8_t word, uint8_t *mac, uint8_t offset) { #endif ; } +// Alternative pin manipulation via PWM control. + bool DCCTimer::isRailcomPin(byte pin) { + return + #ifdef TIMER4_A_PIN + pin==TIMER4_A_PIN || + pin==TIMER4_B_PIN || + pin==TIMER4_C_PIN || + #endif + false; + } void DCCTimer::setPWM(byte pin, bool high) { + byte val=high?1024:0; if (pin==TIMER1_A_PIN) { TCCR1A |= _BV(COM1A1); - OCR1A= high?1024:0; + OCR1A= val; } else if (pin==TIMER1_B_PIN) { TCCR1A |= _BV(COM1B1); - OCR1B= high?1024:0; + OCR1B= val; } #ifdef TIMER1_C_PIN else if (pin==TIMER1_C_PIN) { TCCR1A |= _BV(COM1C1); - OCR1C= high?1024:0; + OCR1C= val; + } + #endif + #ifdef TIMER4_A_PIN + else if (pin==TIMER4_A_PIN) { + TCCR4A |= _BV(COM4A1); //?????????????????????????????????? + OCR4A= val; + } + #endif + #ifdef TIMER4_B_PIN + else if (pin==TIMER4_B_PIN) { + TCCR4B |= _BV(COM4B1); //?????????????????????????????????? + OCR4B= val; + } + #endif + #ifdef TIMER4_C_PIN + else if (pin==TIMER4_C_PIN) { + TCCR4C |= _BV(COM4C1); //?????????????????????????????????? + OCR4C= val; } #endif } diff --git a/DCCTimer.h b/DCCTimer.h index 0c3274c..0452bb7 100644 --- a/DCCTimer.h +++ b/DCCTimer.h @@ -9,6 +9,7 @@ class DCCTimer { static void begin(INTERRUPT_CALLBACK interrupt); static void getSimulatedMacAddress(byte mac[6]); static bool isPWMPin(byte pin); + static bool isRailcomPin(byte pin); static void setPWM(byte pin, bool high); #if (defined(TEENSYDUINO) && !defined(__IMXRT1062__)) static void read_mac(byte mac[6]); diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index df88e5d..e75060e 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -46,8 +46,12 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) { && (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 (MotorDriver::usePWM) + MotorDriver::useRailcom= MotorDriver::usePWM && mainDriver->isRailcomCapable() && progDriver->isRailcomCapable(); + + if (MotorDriver::usePWM){ DIAG(F("Signal pin config: high accuracy waveform")); + if (MotorDriver::useRailcom) DIAG(F("Railcom Enabled")); + } else DIAG(F("Signal pin config: normal accuracy waveform")); DCCTimer::begin(DCCWaveform::interruptHandler); @@ -205,6 +209,10 @@ void DCCWaveform::interrupt2() { if (remainingPreambles > 0 ) { state=WAVE_MID_1; // switch state to trigger LOW on next interrupt remainingPreambles--; + // Railcom cutout + if (remainingPreambles==requiredPreambles-2) motorDriver->setRailcomCutout(true); + else if (remainingPreambles==requiredPreambles-4) motorDriver->setRailcomCutout(false); + // Update free memory diagnostic as we don't have anything else to do this time. // Allow for checkAck and its called functions using 22 bytes more. updateMinimumFreeMemory(22); diff --git a/MotorDriver.cpp b/MotorDriver.cpp index f51ee04..25a8b61 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -27,6 +27,8 @@ #define isLOW(fastpin) (!isHIGH(fastpin)) bool MotorDriver::usePWM=false; +bool MotorDriver::useRailcom=false; + bool MotorDriver::commonFaultPin=false; MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin, @@ -84,6 +86,10 @@ bool MotorDriver::isPWMCapable() { return (!dualSignal) && DCCTimer::isPWMPin(signalPin); } +bool MotorDriver::isRailcomCapable() { + return (!dualSignal) && DCCTimer::isRailcomPin(brakePin); +} + void MotorDriver::setPower(bool on) { if (on) { @@ -110,6 +116,10 @@ void MotorDriver::setBrake(bool on) { else setLOW(fastBrakePin); } +void MotorDriver::setRailcomCutout(bool on) { + if (useRailcom) DCCTimer::setPWM(brakePin,on); +} + void MotorDriver::setSignal( bool high) { if (usePWM) { DCCTimer::setPWM(signalPin,high); diff --git a/MotorDriver.h b/MotorDriver.h index 08db049..4723339 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -54,8 +54,11 @@ class MotorDriver { return rawCurrentTripValue; } bool isPWMCapable(); + bool isRailcomCapable(); bool canMeasureCurrent(); + void setRailcomCutout(bool on); static bool usePWM; + static bool useRailcom; static bool commonFaultPin; // This is a stupid motor shield which has only a common fault pin for both outputs inline byte getFaultPin() { return faultPin; diff --git a/MotorDrivers.h b/MotorDrivers.h index e011b0f..6c0cbbb 100644 --- a/MotorDrivers.h +++ b/MotorDrivers.h @@ -27,6 +27,11 @@ new MotorDriver(3, 12, UNUSED_PIN, UNUSED_PIN, A0, 2.99, 2000, UNUSED_PIN), \ new MotorDriver(11, 13, UNUSED_PIN, UNUSED_PIN, A1, 2.99, 2000, UNUSED_PIN) +// Arduino standard Motor Shield with railcom (mega brakes on 6,7 require jumpers ) +#define STANDARD_WITH_RAILCOM F("STANDARD_WITH_RAILCOM"), \ + new MotorDriver(3, 12, UNUSED_PIN, 6, A0, 2.99, 2000, UNUSED_PIN), \ + new MotorDriver(11, 13, UNUSED_PIN, 7, A1, 2.99, 2000, UNUSED_PIN) + // Pololu Motor Shield #define POLOLU_MOTOR_SHIELD F("POLOLU_MOTOR_SHIELD"), \ new MotorDriver( 9, 7, UNUSED_PIN, -4, A0, 18, 3000, 12), \