diff --git a/DCCRMT.cpp b/DCCRMT.cpp
new file mode 100644
index 0000000..5186ecf
--- /dev/null
+++ b/DCCRMT.cpp
@@ -0,0 +1,138 @@
+/*
+ * © 2021, Harald Barth.
+ *
+ * This file is part of DCC-EX
+ *
+ * This is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * It is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CommandStation. If not, see .
+ */
+
+#include "defines.h"
+#include "DIAG.h"
+#include "DCCRMT.h"
+#include "soc/periph_defs.h"
+#include "driver/periph_ctrl.h"
+
+#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4,2,0)
+#error wrong IDF version
+#endif
+
+void setDCCBit1(rmt_item32_t* item) {
+ item->level0 = 1;
+ item->duration0 = DCC_1_HALFPERIOD;
+ item->level1 = 0;
+ item->duration1 = DCC_1_HALFPERIOD;
+}
+
+void setDCCBit0(rmt_item32_t* item) {
+ item->level0 = 1;
+ item->duration0 = DCC_0_HALFPERIOD;
+ item->level1 = 0;
+ item->duration1 = DCC_0_HALFPERIOD;
+}
+
+void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) {
+ BaseType_t wtf = pdFALSE;
+ RMTPin *tt = (RMTPin *)t;
+ //DIAG(F("interrupt %d"), tt->idleLen);
+ tt->RMTinterrupt(channel,t);
+ rmt_tx_start(channel,true);
+ portYIELD_FROM_ISR(wtf);
+}
+
+RMTPin::RMTPin(byte pin, byte ch, byte plen) {
+
+ // preamble
+ preambleLen = plen+1;
+ preamble = (rmt_item32_t*)malloc(preambleLen*sizeof(rmt_item32_t));
+ for (byte n=0; npreambleNext) {
+ rmt_fill_tx_items(channel, obj->preamble, obj->preambleLen, 0);
+ //obj->preambleNext = false;
+ } else {
+ if (obj->dataNext) {
+ rmt_fill_tx_items(channel, obj->packetBits, obj->packetLen, 0);
+ } else {
+ // here we should not get as now we need to send idle packet
+ rmt_fill_tx_items(channel, obj->idle, obj->idleLen, 0);
+ }
+ obj->preambleNext = true;
+ }
+ rmt_tx_start(channel,true);
+ DIAG(F("START"));
+ */
+}
diff --git a/DCCRMT.h b/DCCRMT.h
new file mode 100644
index 0000000..58f77de
--- /dev/null
+++ b/DCCRMT.h
@@ -0,0 +1,51 @@
+/*
+ * © 2021, Harald Barth.
+ *
+ * This file is part of DCC-EX
+ *
+ * This is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * It is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CommandStation. If not, see .
+ */
+
+#pragma once
+#include
+#include "driver/rmt.h"
+#include "soc/rmt_reg.h"
+#include "soc/rmt_struct.h"
+
+#define DCC_1_HALFPERIOD 4640 // 1 / 80000000 * 4640 = 58us
+#define DCC_0_HALFPERIOD 8000
+
+class RMTPin {
+ public:
+ RMTPin(byte pin, byte ch, byte plen);
+ void IRAM_ATTR RMTinterrupt(rmt_channel_t, void *t);
+
+ static RMTPin mainRMTPin;
+ static RMTPin progRMTPin;
+
+ // private:
+
+ rmt_channel_t channel;
+ // 3 types of data to send, preamble and then idle or data
+ // if this is prog track, idle will contain reset instead
+ rmt_item32_t *idle;
+ byte idleLen;
+ rmt_item32_t *preamble;
+ byte preambleLen;
+ rmt_item32_t packetBits[64];
+ byte packetLen;
+ // flags
+ volatile bool preambleNext = true; // alternate between preamble and content
+ volatile bool dataNext = false; // do we have real data available or send idle
+};
diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp
index 94cd91d..505583f 100644
--- a/DCCWaveform.cpp
+++ b/DCCWaveform.cpp
@@ -25,6 +25,7 @@
#include "DCCTimer.h"
#include "DIAG.h"
#include "freeMemory.h"
+#include "DCCRMT.h"
DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true);
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
@@ -37,6 +38,9 @@ volatile uint8_t DCCWaveform::numAckSamples=0;
uint8_t DCCWaveform::trailingEdgeCounter=0;
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
+
+ RMTPin *p = new RMTPin(21, 0, PREAMBLE_BITS_MAIN);
+
mainTrack.motorDriver=mainDriver;
progTrack.motorDriver=progDriver;
progTripValue = progDriver->mA2raw(TRIP_CURRENT_PROG); // need only calculate once hence static
@@ -47,11 +51,14 @@ 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)
DIAG(F("Signal pin config: high accuracy waveform"));
else
DIAG(F("Signal pin config: normal accuracy waveform"));
DCCTimer::begin(DCCWaveform::interruptHandler);
+ */
+ DIAG(F("No waveform"));
}
#ifdef SLOW_ANALOG_READ
diff --git a/WifiESP32.cpp b/WifiESP32.cpp
index 49b2116..48d40d6 100644
--- a/WifiESP32.cpp
+++ b/WifiESP32.cpp
@@ -17,6 +17,7 @@
along with CommandStation. If not, see .
*/
+#include
#include "defines.h"
#if defined(ARDUINO_ARCH_ESP32)
#include
@@ -231,7 +232,7 @@ void WifiESP::loop() {
}
}
} //connected
- yield();
+
// when loop() is running on core0 we must
// feed the core0 wdt ourselves as yield()
// is not necessarily yielding to a low
@@ -240,5 +241,6 @@ void WifiESP::loop() {
// arduio IDE startup routines.
if (xPortGetCoreID() == 0)
feedTheDog0();
+ yield();
}
#endif //ESP32