1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-26 17:46:14 +01:00

Merge branch 'PORTX_HAL' of https://github.com/DCC-EX/CommandStation-EX into PORTX_HAL

This commit is contained in:
pmantoine 2022-08-13 17:32:25 +08:00
commit 4a84ea1b43
6 changed files with 46 additions and 17 deletions

View File

@ -69,7 +69,7 @@ void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) {
if (tt) tt->RMTinterrupt(); if (tt) tt->RMTinterrupt();
} }
RMTChannel::RMTChannel(byte pin, bool isMain) { RMTChannel::RMTChannel(pinpair pins, bool isMain) {
byte ch; byte ch;
byte plen; byte plen;
if (isMain) { if (isMain) {
@ -119,13 +119,14 @@ RMTChannel::RMTChannel(byte pin, bool isMain) {
config.rmt_mode = RMT_MODE_TX; config.rmt_mode = RMT_MODE_TX;
config.channel = channel = (rmt_channel_t)ch; config.channel = channel = (rmt_channel_t)ch;
config.clk_div = RMT_CLOCK_DIVIDER; config.clk_div = RMT_CLOCK_DIVIDER;
config.gpio_num = (gpio_num_t)pin; config.gpio_num = (gpio_num_t)pins.pin;
config.mem_block_num = 2; // With longest DCC packet 11 inc checksum (future expansion) config.mem_block_num = 2; // With longest DCC packet 11 inc checksum (future expansion)
// number of bits needed is 22preamble + start + // number of bits needed is 22preamble + start +
// 11*9 + extrazero + EOT = 124 // 11*9 + extrazero + EOT = 124
// 2 mem block of 64 RMT items should be enough // 2 mem block of 64 RMT items should be enough
ESP_ERROR_CHECK(rmt_config(&config)); ESP_ERROR_CHECK(rmt_config(&config));
addPin(pins.invpin, true);
/* /*
// test: config another gpio pin // test: config another gpio pin
gpio_num_t gpioNum = (gpio_num_t)(pin-1); gpio_num_t gpioNum = (gpio_num_t)(pin-1);
@ -213,14 +214,19 @@ void IRAM_ATTR RMTChannel::RMTinterrupt() {
dataRepeat--; dataRepeat--;
} }
bool RMTChannel::addPin(byte pin) { bool RMTChannel::addPin(byte pin, bool inverted) {
if (pin == UNUSED_PIN)
return true;
gpio_num_t gpioNum = (gpio_num_t)(pin); gpio_num_t gpioNum = (gpio_num_t)(pin);
esp_err_t err; esp_err_t err;
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpioNum], PIN_FUNC_GPIO); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpioNum], PIN_FUNC_GPIO);
err = gpio_set_direction(gpioNum, GPIO_MODE_OUTPUT); err = gpio_set_direction(gpioNum, GPIO_MODE_OUTPUT);
if (err != ESP_OK) return false; if (err != ESP_OK) return false;
gpio_matrix_out(gpioNum, RMT_SIG_OUT0_IDX+channel, 0, 0); gpio_matrix_out(gpioNum, RMT_SIG_OUT0_IDX+channel, inverted, 0);
if (err != ESP_OK) return false; if (err != ESP_OK) return false;
return true; return true;
} }
bool RMTChannel::addPin(pinpair pins) {
return addPin(pins.pin) && addPin(pins.invpin, true);
}
#endif //ESP32 #endif //ESP32

View File

@ -23,6 +23,7 @@
#include "driver/rmt.h" #include "driver/rmt.h"
#include "soc/rmt_reg.h" #include "soc/rmt_reg.h"
#include "soc/rmt_struct.h" #include "soc/rmt_struct.h"
#include "MotorDriver.h" // for class pinpair
// make calculations easy and set up for microseconds // make calculations easy and set up for microseconds
#define RMT_CLOCK_DIVIDER 80 #define RMT_CLOCK_DIVIDER 80
@ -31,8 +32,9 @@
class RMTChannel { class RMTChannel {
public: public:
RMTChannel(byte pin, bool isMain); RMTChannel(pinpair pins, bool isMain);
bool addPin(byte pin); bool addPin(byte pin, bool inverted=0);
bool addPin(pinpair pins);
void IRAM_ATTR RMTinterrupt(); void IRAM_ATTR RMTinterrupt();
void RMTprefill(); void RMTprefill();
//int RMTfillData(dccPacket packet); //int RMTfillData(dccPacket packet);

View File

@ -211,22 +211,24 @@ DCCWaveform::DCCWaveform(byte preambleBits, bool isMain) {
} }
void DCCWaveform::begin() { void DCCWaveform::begin() {
for(const auto& md: TrackManager::getMainDrivers()) { for(const auto& md: TrackManager::getMainDrivers()) {
pinpair p = md->getSignalPin();
if(rmtMainChannel) { if(rmtMainChannel) {
DIAG(F("added pin %d to MAIN channel"), md->getSignalPin()); DIAG(F("added pins %d %d to MAIN channel"), p.pin, p.invpin);
rmtMainChannel->addPin(md->getSignalPin()); // add pin to existing main channel rmtMainChannel->addPin(p); // add pin to existing main channel
} else { } else {
DIAG(F("new MAIN channel with pin %d"), md->getSignalPin()); DIAG(F("new MAIN channel with pins %d %d"), p.pin, p.invpin);
rmtMainChannel = new RMTChannel(md->getSignalPin(), true); /* create new main channel */ rmtMainChannel = new RMTChannel(p, true); /* create new main channel */
} }
} }
MotorDriver *md = TrackManager::getProgDriver(); MotorDriver *md = TrackManager::getProgDriver();
if (md) { if (md) {
pinpair p = md->getSignalPin();
if (rmtProgChannel) { if (rmtProgChannel) {
DIAG(F("added pin %d to PROG channel"), md->getSignalPin()); DIAG(F("added pins %d %d to PROG channel"), p.pin, p.invpin);
rmtProgChannel->addPin(md->getSignalPin()); // add pin to existing prog channel rmtProgChannel->addPin(p); // add pin to existing prog channel
} else { } else {
DIAG(F("new PROGchannel with pin %d"), TrackManager::getProgDriver()->getSignalPin()); DIAG(F("new PROGchannel with pins %d %d"), p.pin, p.invpin);
rmtProgChannel = new RMTChannel(TrackManager::getProgDriver()->getSignalPin(), false); rmtProgChannel = new RMTChannel(p, false);
} }
} }
} }

View File

@ -59,10 +59,12 @@ class DCCWaveform {
#else #else
// extrafudge is added when we know that the resets will first come extrafudge packets in the future // extrafudge is added when we know that the resets will first come extrafudge packets in the future
inline void clearResets(byte extrafudge=0) { inline void clearResets(byte extrafudge=0) {
if ((isMainTrack ? rmtMainChannel : rmtProgChannel) == NULL) return;
resetPacketBase = isMainTrack ? rmtMainChannel->packetCount() : rmtProgChannel->packetCount(); resetPacketBase = isMainTrack ? rmtMainChannel->packetCount() : rmtProgChannel->packetCount();
resetPacketBase += extrafudge; resetPacketBase += extrafudge;
}; };
inline byte getResets() { inline byte getResets() {
if ((isMainTrack ? rmtMainChannel : rmtProgChannel) == NULL) return 0;
uint32_t packetcount = isMainTrack ? uint32_t packetcount = isMainTrack ?
rmtMainChannel->packetCount() : rmtProgChannel->packetCount(); rmtMainChannel->packetCount() : rmtProgChannel->packetCount();
uint32_t count = packetcount - resetPacketBase; // Beware of unsigned interger arithmetic. uint32_t count = packetcount - resetPacketBase; // Beware of unsigned interger arithmetic.

View File

@ -77,6 +77,16 @@
#define UNUSED_PIN 127 // inside int8_t #define UNUSED_PIN 127 // inside int8_t
#endif #endif
class pinpair {
public:
pinpair(byte p1, byte p2) {
pin = p1;
invpin = p2;
};
byte pin = UNUSED_PIN;
byte invpin = UNUSED_PIN;
};
#if defined(__IMXRT1062__) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_STM32) #if defined(__IMXRT1062__) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_STM32)
typedef uint32_t portreg_t; typedef uint32_t portreg_t;
#else #else
@ -134,7 +144,7 @@ class MotorDriver {
else else
pinMode(signalPin, INPUT); pinMode(signalPin, INPUT);
}; };
inline byte getSignalPin() { return signalPin; }; inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); };
virtual void setDCSignal(byte speedByte); virtual void setDCSignal(byte speedByte);
inline void detachDCSignal() { inline void detachDCSignal() {
#if defined(__arm__) #if defined(__arm__)

View File

@ -140,8 +140,15 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
// remove pin from MUX matrix and turn it off // remove pin from MUX matrix and turn it off
DIAG(F("Track=%c remove pin %d"),trackToSet+'A', track[trackToSet]->getSignalPin()); pinpair p = track[trackToSet]->getSignalPin();
gpio_reset_pin((gpio_num_t)track[trackToSet]->getSignalPin()); DIAG(F("Track=%c remove pin %d"),trackToSet+'A', p.pin);
gpio_reset_pin((gpio_num_t)p.pin);
pinMode(p.pin, OUTPUT); // gpio_reset_pin may reset to input
if (p.invpin != UNUSED_PIN) {
DIAG(F("Track=%c remove ^pin %d"),trackToSet+'A', p.invpin);
gpio_reset_pin((gpio_num_t)p.invpin);
pinMode(p.invpin, OUTPUT); // gpio_reset_pin may reset to input
}
#endif #endif
if (mode==TRACK_MODE_PROG) { if (mode==TRACK_MODE_PROG) {
// only allow 1 track to be prog // only allow 1 track to be prog