mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-23 16:16:13 +01:00
Compare commits
4 Commits
02bf50b909
...
cff4075937
Author | SHA1 | Date | |
---|---|---|---|
|
cff4075937 | ||
|
84b90ae757 | ||
|
6d7d2325da | ||
|
fdc956576b |
|
@ -66,7 +66,9 @@ class DCCTimer {
|
||||||
static void ackRailcomTimer();
|
static void ackRailcomTimer();
|
||||||
static void DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency);
|
static void DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency);
|
||||||
static void DCCEXanalogWrite(uint8_t pin, int value);
|
static void DCCEXanalogWrite(uint8_t pin, int value);
|
||||||
|
static void DCCEXledcDetachPin(uint8_t pin);
|
||||||
|
static void DCCEXanalogCopyChannel(uint8_t frompin, uint8_t topin);
|
||||||
|
static void DCCEXInrushControlOn(uint8_t pin, int duty);
|
||||||
// Update low ram level. Allow for extra bytes to be specified
|
// Update low ram level. Allow for extra bytes to be specified
|
||||||
// by estimation or inspection, that may be used by other
|
// by estimation or inspection, that may be used by other
|
||||||
// called subroutines. Must be called with interrupts disabled.
|
// called subroutines. Must be called with interrupts disabled.
|
||||||
|
|
|
@ -78,6 +78,7 @@ int DCCTimer::freeMemory() {
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#include "DIAG.h"
|
||||||
#include <driver/adc.h>
|
#include <driver/adc.h>
|
||||||
#include <soc/sens_reg.h>
|
#include <soc/sens_reg.h>
|
||||||
#include <soc/sens_struct.h>
|
#include <soc/sens_struct.h>
|
||||||
|
@ -154,8 +155,10 @@ void DCCTimer::reset() {
|
||||||
void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) {
|
void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t f) {
|
||||||
if (f >= 16)
|
if (f >= 16)
|
||||||
DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, f);
|
DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, f);
|
||||||
else if (f == 7)
|
/*
|
||||||
|
else if (f == 7) // not used on ESP32
|
||||||
DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 62500);
|
DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 62500);
|
||||||
|
*/
|
||||||
else if (f >= 4)
|
else if (f >= 4)
|
||||||
DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 32000);
|
DCCTimer::DCCEXanalogWriteFrequencyInternal(pin, 32000);
|
||||||
else if (f >= 3)
|
else if (f >= 3)
|
||||||
|
@ -188,22 +191,65 @@ void DCCTimer::DCCEXanalogWriteFrequencyInternal(uint8_t pin, uint32_t frequency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DCCTimer::DCCEXledcDetachPin(uint8_t pin) {
|
||||||
|
DIAG(F("Clear pin %d channel"), pin);
|
||||||
|
pin_to_channel[pin] = 0;
|
||||||
|
pinMatrixOutDetach(pin, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DCCTimer::DCCEXanalogCopyChannel(uint8_t frompin, uint8_t topin) {
|
||||||
|
DIAG(F("Pin %d copied to %d channel %d"), frompin, topin, pin_to_channel[frompin]);
|
||||||
|
pin_to_channel[topin] = pin_to_channel[frompin];
|
||||||
|
ledcAttachPin(topin, pin_to_channel[topin]);
|
||||||
|
}
|
||||||
void DCCTimer::DCCEXanalogWrite(uint8_t pin, int value) {
|
void DCCTimer::DCCEXanalogWrite(uint8_t pin, int value) {
|
||||||
|
// This allocates channels 15, 13, 11, ....
|
||||||
|
// so each channel gets its own timer.
|
||||||
if (pin < SOC_GPIO_PIN_COUNT) {
|
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||||
if (pin_to_channel[pin] == 0) {
|
if (pin_to_channel[pin] == 0) {
|
||||||
|
int search_channel;
|
||||||
|
int n;
|
||||||
if (!cnt_channel) {
|
if (!cnt_channel) {
|
||||||
log_e("No more PWM channels available! All %u already used", LEDC_CHANNELS);
|
log_e("No more PWM channels available! All %u already used", LEDC_CHANNELS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pin_to_channel[pin] = --cnt_channel;
|
// search for free channels top down
|
||||||
ledcSetup(cnt_channel, 1000, 8);
|
for (search_channel=LEDC_CHANNELS-1; search_channel >=cnt_channel; search_channel -= 2) {
|
||||||
ledcAttachPin(pin, cnt_channel);
|
bool chanused = false;
|
||||||
|
for (n=0; n < SOC_GPIO_PIN_COUNT; n++) {
|
||||||
|
if (pin_to_channel[n] == search_channel) { // current search_channel used
|
||||||
|
chanused = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chanused)
|
||||||
|
continue;
|
||||||
|
if (n == SOC_GPIO_PIN_COUNT) // current search_channel unused
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (search_channel >= cnt_channel) {
|
||||||
|
pin_to_channel[pin] = search_channel;
|
||||||
|
DIAG(F("Pin %d assigned to search channel %d"), pin, search_channel);
|
||||||
|
} else {
|
||||||
|
pin_to_channel[pin] = --cnt_channel; // This sets 15, 13, ...
|
||||||
|
DIAG(F("Pin %d assigned to new channel %d"), pin, cnt_channel);
|
||||||
|
--cnt_channel; // Now we are at 14, 12, ...
|
||||||
|
}
|
||||||
|
ledcSetup(pin_to_channel[pin], 1000, 8);
|
||||||
|
ledcAttachPin(pin, pin_to_channel[pin]);
|
||||||
} else {
|
} else {
|
||||||
|
//DIAG(F("Pin %d assigned to old channel %d"), pin, pin_to_channel[pin]);
|
||||||
ledcAttachPin(pin, pin_to_channel[pin]);
|
ledcAttachPin(pin, pin_to_channel[pin]);
|
||||||
}
|
}
|
||||||
ledcWrite(pin_to_channel[pin], value);
|
ledcWrite(pin_to_channel[pin], value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void DCCTimer::DCCEXInrushControlOn(uint8_t pin, int duty) {
|
||||||
|
ledcSetup(0, 62500, 8);
|
||||||
|
ledcAttachPin(pin, 0);
|
||||||
|
ledcWrite(0, duty);
|
||||||
|
}
|
||||||
|
|
||||||
int ADCee::init(uint8_t pin) {
|
int ADCee::init(uint8_t pin) {
|
||||||
pinMode(pin, ANALOG);
|
pinMode(pin, ANALOG);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define GITHUB_SHA "devel-202404012205Z"
|
#define GITHUB_SHA "devel-202404042311Z"
|
||||||
|
|
|
@ -404,17 +404,17 @@ void MotorDriver::setDCSignal(byte speedcode, uint8_t frequency /*default =0*/)
|
||||||
void MotorDriver::throttleInrush(bool on) {
|
void MotorDriver::throttleInrush(bool on) {
|
||||||
if (brakePin == UNUSED_PIN)
|
if (brakePin == UNUSED_PIN)
|
||||||
return;
|
return;
|
||||||
if ( !(trackMode & (TRACK_MODE_MAIN | TRACK_MODE_PROG | TRACK_MODE_EXT)))
|
if ( !(trackMode & (TRACK_MODE_MAIN | TRACK_MODE_PROG | TRACK_MODE_EXT | TRACK_MODE_BOOST)))
|
||||||
return;
|
return;
|
||||||
byte duty = on ? 207 : 0; // duty of 81% at 62500Hz this gives pauses of 3usec
|
byte duty = on ? 207 : 0; // duty of 81% at 62500Hz this gives pauses of 3usec
|
||||||
if (invertBrake)
|
if (invertBrake)
|
||||||
duty = 255-duty;
|
duty = 255-duty;
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
if(on) {
|
if(on) {
|
||||||
DCCTimer::DCCEXanalogWrite(brakePin,duty);
|
DCCTimer::DCCEXInrushControlOn(brakePin, duty);
|
||||||
DCCTimer::DCCEXanalogWriteFrequency(brakePin, 7); // 7 means max
|
|
||||||
} else {
|
} else {
|
||||||
ledcDetachPin(brakePin);
|
ledcDetachPin(brakePin); // not DCCTimer::DCCEXledcDetachPin() as we have not
|
||||||
|
// registered the pin in the pin to channel array
|
||||||
}
|
}
|
||||||
#elif defined(ARDUINO_ARCH_STM32)
|
#elif defined(ARDUINO_ARCH_STM32)
|
||||||
if(on) {
|
if(on) {
|
||||||
|
|
|
@ -193,13 +193,14 @@ class MotorDriver {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); };
|
inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); };
|
||||||
|
inline byte getBrakePin() { return brakePin; };
|
||||||
void setDCSignal(byte speedByte, uint8_t frequency=0);
|
void setDCSignal(byte speedByte, uint8_t frequency=0);
|
||||||
void throttleInrush(bool on);
|
void throttleInrush(bool on);
|
||||||
inline void detachDCSignal() {
|
inline void detachDCSignal() {
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
pinMode(brakePin, OUTPUT);
|
pinMode(brakePin, OUTPUT);
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
ledcDetachPin(brakePin);
|
DCCTimer::DCCEXledcDetachPin(brakePin);
|
||||||
#else
|
#else
|
||||||
setDCSignal(128);
|
setDCSignal(128);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -252,13 +252,32 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
|
||||||
track[trackToSet]->makeProgTrack(false); // only the prog track knows it's type
|
track[trackToSet]->makeProgTrack(false); // only the prog track knows it's type
|
||||||
}
|
}
|
||||||
track[trackToSet]->setMode(mode);
|
track[trackToSet]->setMode(mode);
|
||||||
trackDCAddr[trackToSet]=dcAddr;
|
|
||||||
|
|
||||||
// When a track is switched, we must clear any side effects of its previous
|
// When a track is switched, we must clear any side effects of its previous
|
||||||
// state, otherwise trains run away or just dont move.
|
// state, otherwise trains run away or just dont move.
|
||||||
|
|
||||||
// This can be done BEFORE the PWM-Timer evaluation (methinks)
|
// This can be done BEFORE the PWM-Timer evaluation (methinks)
|
||||||
if (!(mode & TRACK_MODE_DC)) {
|
if (mode & TRACK_MODE_DC) {
|
||||||
|
if (trackDCAddr[trackToSet] != dcAddr) {
|
||||||
|
// if we change dcAddr, detach first old signal
|
||||||
|
track[trackToSet]->detachDCSignal();
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
int trackfound = -1;
|
||||||
|
FOR_EACH_TRACK(t) {
|
||||||
|
if ((track[t]->getMode() & TRACK_MODE_DC) && trackDCAddr[t] == dcAddr) {
|
||||||
|
trackfound = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trackfound > -1) {
|
||||||
|
DCCTimer::DCCEXanalogCopyChannel(track[trackfound]->getBrakePin(),
|
||||||
|
track[trackToSet]->getBrakePin());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// set future DC Addr;
|
||||||
|
trackDCAddr[trackToSet]=dcAddr;
|
||||||
|
} else {
|
||||||
// DCC tracks need to have set the PWM to zero or they will not work.
|
// DCC tracks need to have set the PWM to zero or they will not work.
|
||||||
track[trackToSet]->detachDCSignal();
|
track[trackToSet]->detachDCSignal();
|
||||||
track[trackToSet]->setBrake(false);
|
track[trackToSet]->setBrake(false);
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
#define VERSION "5.2.42"
|
#define VERSION "5.2.43"
|
||||||
|
// 5.2.43 - ESP32 rewrite PWM LEDC to use pin mux
|
||||||
// 5.2.42 - ESP32 Bugfix: Uninitialized stack variable
|
// 5.2.42 - ESP32 Bugfix: Uninitialized stack variable
|
||||||
// 5.2.41 - Update rotary encoder default address to 0x67
|
// 5.2.41 - Update rotary encoder default address to 0x67
|
||||||
// 5.2.40 - Allow no shield
|
// 5.2.40 - Allow no shield
|
||||||
|
|
Loading…
Reference in New Issue
Block a user