From 67e8c04314a51cd04ed1499d92c1c07cb0cbd88e Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sat, 30 Jul 2022 21:11:51 +0200 Subject: [PATCH] in principle schedules packets --- DCC.cpp | 8 +++++++- DCCRMT.cpp | 25 ++++++++++++++++++------- DCCRMT.h | 10 ++-------- MotorDriver.cpp | 24 +++++++++++++++++++----- MotorDriver.h | 6 +++++- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/DCC.cpp b/DCC.cpp index 74397ef..bc9160f 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -71,7 +71,13 @@ void DCC::begin() { // Add main and prog drivers to the main and prog packet sources (dcc-tracks). std::vector v; - v = MotorDriverContainer::mDC.getDriverType(RMT_MAIN|TIMER_MAIN); + + v = MotorDriverContainer::mDC.getDriverType(RMT_MAIN); + + v.front()->setChannel(new RMTChannel(v.front()->getSignalPin(), true)); + + + 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); diff --git a/DCCRMT.cpp b/DCCRMT.cpp index e26dd18..1ac1aa4 100644 --- a/DCCRMT.cpp +++ b/DCCRMT.cpp @@ -62,8 +62,17 @@ void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) { tt->RMTinterrupt(); } -RMTChannel::RMTChannel(byte pin, byte ch, byte plen, bool isMain) { - +RMTChannel::RMTChannel(byte pin, bool isMain) { + byte ch; + byte plen; + if (isMain) { + ch = 0; + plen = PREAMBLE_BITS_MAIN; + } else { + ch = 2; + plen = PREAMBLE_BITS_PROG; + } + // preamble preambleLen = plen+2; // plen 1 bits, one 0 bit and one EOF marker preamble = (rmt_item32_t*)malloc(preambleLen*sizeof(rmt_item32_t)); @@ -146,17 +155,19 @@ void RMTChannel::RMTprefill() { const byte transmitMask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; //bool RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCount=0) { -bool RMTChannel::RMTfillData(dccPacket packet) { +int RMTChannel::RMTfillData(dccPacket packet) { // dataReady: Signals to then interrupt routine. It is set when // we have data in the channel buffer which can be copied out // to the HW. dataRepeat on the other hand signals back to // the caller of this function if the data has been sent enough // times (0 to 3 means 1 to 4 times in total). - if (dataReady == true || dataRepeat > 0) // we have still old work to do - return false; + if (dataReady == true) + return 1000; + if (dataRepeat > 0) // we have still old work to do + return dataRepeat; if (DATA_LEN(packet.length) > maxDataLen) { // this would overun our allocated memory for data DIAG(F("Can not convert DCC bytes # %d to DCC bits %d, buffer too small"), packet.length, maxDataLen); - return false; // something very broken, can not convert packet + return -1; // something very broken, can not convert packet } byte *buffer = packet.data; @@ -177,7 +188,7 @@ bool RMTChannel::RMTfillData(dccPacket packet) { dataLen = bitcounter; dataReady = true; dataRepeat = packet.repeat+1; // repeatCount of 0 means send once - return true; + return 0; } void IRAM_ATTR RMTChannel::RMTinterrupt() { diff --git a/DCCRMT.h b/DCCRMT.h index 94234e7..6e75219 100644 --- a/DCCRMT.h +++ b/DCCRMT.h @@ -32,16 +32,10 @@ class RMTChannel { public: - inline RMTChannel(byte pin, bool isMain) { - if (isMain) - RMTChannel(pin, 0, PREAMBLE_BITS_MAIN, 1); - else - RMTChannel(pin, 2, PREAMBLE_BITS_PROG, 0); - }; - RMTChannel(byte pin, byte ch, byte plen, bool isProg); + RMTChannel(byte pin, bool isMain); void IRAM_ATTR RMTinterrupt(); void RMTprefill(); - bool RMTfillData(dccPacket packet); + int RMTfillData(dccPacket packet); //bool RMTfillData(const byte buffer[], byte byteCount, byte repeatCount); static RMTChannel mainRMTChannel; diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 5f3d68a..5b6d6c3 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -38,11 +38,14 @@ MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8 getFastPin(F("POWER"),powerPin,fastPowerPin); pinMode(powerPin, OUTPUT); - if (dtype == RMT_MAIN) { + if (dtype & (RMT_MAIN | RMT_PROG)) { signalPin=signal_pin; + /* #if defined(ARDUINO_ARCH_ESP32) - rmtChannel = new RMTChannel(signalPin, true); // true: isMain + //rmtChannel = new RMTChannel(signalPin, 0, PREAMBLE_BITS_MAIN, true); // true: isMain + rmtChannel = new RMTChannel(signalPin, dtype == RMT_MAIN); // true: isMain #endif + */ dualSignal=false; } else if (dtype & (TIMER_MAIN | TIMER_PROG)) { signalPin=signal_pin; @@ -209,7 +212,10 @@ void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & res } bool MotorDriver::schedulePacket(dccPacket packet) { - if(!rmtChannel) return true; // fake success if functionality is not there + if(!rmtChannel) { + DIAG(F("no rmt Channel")); + return true; // fake success if functionality is not there + } outQueue.push(packet); uint16_t size = outQueue.size(); @@ -220,8 +226,16 @@ bool MotorDriver::schedulePacket(dccPacket packet) { } void MotorDriver::loop() { - if (rmtChannel && !outQueue.empty() && rmtChannel->RMTfillData(outQueue.front())) - outQueue.pop(); + int r; + if (rmtChannel && !outQueue.empty()) { + r = rmtChannel->RMTfillData(outQueue.front()); + if (r == 0) { + DIAG(F("r=OK")); + outQueue.pop(); + } + else + DIAG(F("r=%d"), r); + } } MotorDriverContainer::MotorDriverContainer(const FSH * motorShieldName, diff --git a/MotorDriver.h b/MotorDriver.h index 65f97f2..95d00fe 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -83,12 +83,16 @@ class MotorDriver { static bool commonFaultPin; // This is a stupid motor shield which has only a common fault pin for both outputs inline byte getFaultPin() { return faultPin; - } + }; + inline byte getSignalPin() { + return signalPin; + }; #if defined(ARDUINO_ARCH_ESP32) void loop(); inline driverType type() { return dtype; }; inline void setType(driverType t) { dtype = t; }; bool schedulePacket(dccPacket packet); + inline void setChannel(RMTChannel * r) { rmtChannel = r; }; #endif private: