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

Compare commits

..

8 Commits

Author SHA1 Message Date
George
1b70247edf
Merge d1775c69e6 into 4e491a1e56 2024-10-02 12:47:46 -04:00
Harald Barth
4e491a1e56 Typo 2024-06-02 21:17:30 +02:00
Harald Barth
430161ef60 ESP32: Refuse IDF5 2024-06-02 21:14:46 +02:00
Peter Akers
28d60d4984 Update README.md 2024-02-16 18:02:40 +10:00
peteGSX
3b162996ad EX-IO fixes in version 2024-01-21 07:13:53 +10:00
Harald Barth
fb414a7a50 Bugfix: allocate enough bytes for digital pins. Add more sanity checks when allocating memory 2024-01-20 21:45:09 +01:00
Harald Barth
818e05b425 version 5.0.8 2024-01-10 08:37:54 +01:00
Harald Barth
c5168f030f Do not crash on turnouts without description 2024-01-10 08:25:34 +01:00
5 changed files with 89 additions and 98 deletions

View File

@ -76,8 +76,13 @@ int DCCTimer::freeMemory() {
#endif #endif
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include "esp_idf_version.h"
#if ESP_IDF_VERSION_MAJOR > 4
#error "DCC-EX does not support compiling with IDF version 5.0 or later. Downgrade your ESP32 library to a version that contains IDF version 4. Arduino ESP32 library 3.0.0 is too new. Use 2.0.9 to 2.0.17"
#endif
#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>

View File

@ -259,8 +259,9 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
} }
void RMFT2::setTurnoutHiddenState(Turnout * t) { void RMFT2::setTurnoutHiddenState(Turnout * t) {
// turnout descriptions are in low flash F strings // turnout descriptions are in low flash F strings
t->setHidden(GETFLASH(getTurnoutDescription(t->getId()))==0x01); const FSH *desc = getTurnoutDescription(t->getId());
if (desc) t->setHidden(GETFLASH(desc)==0x01);
} }
char RMFT2::getRouteType(int16_t id) { char RMFT2::getRouteType(int16_t id) {

View File

@ -1,5 +1,6 @@
/* /*
* © 2022, Peter Cole. All rights reserved. * © 2022, Peter Cole. All rights reserved.
* © 2024, Harald Barth. All rights reserved.
* *
* This file is part of EX-CommandStation * This file is part of EX-CommandStation
* *
@ -98,34 +99,53 @@ private:
_numAnaloguePins = receiveBuffer[2]; _numAnaloguePins = receiveBuffer[2];
// See if we already have suitable buffers assigned // See if we already have suitable buffers assigned
size_t digitalBytesNeeded = (_numDigitalPins + 7) / 8; if (_numDigitalPins>0) {
if (_digitalPinBytes < digitalBytesNeeded) { size_t digitalBytesNeeded = (_numDigitalPins + 7) / 8;
// Not enough space, free any existing buffer and allocate a new one if (_digitalPinBytes < digitalBytesNeeded) {
if (_digitalPinBytes > 0) free(_digitalInputStates); // Not enough space, free any existing buffer and allocate a new one
_digitalInputStates = (byte*) calloc(_digitalPinBytes, 1); if (_digitalPinBytes > 0) free(_digitalInputStates);
_digitalPinBytes = digitalBytesNeeded; if ((_digitalInputStates = (byte*) calloc(digitalBytesNeeded, 1)) != NULL) {
} _digitalPinBytes = digitalBytesNeeded;
size_t analogueBytesNeeded = _numAnaloguePins * 2; } else {
if (_analoguePinBytes < analogueBytesNeeded) { DIAG(F("EX-IOExpander I2C:%s ERROR alloc %d bytes"), _I2CAddress.toString(), digitalBytesNeeded);
// Free any existing buffers and allocate new ones. _deviceState = DEVSTATE_FAILED;
if (_analoguePinBytes > 0) { _digitalPinBytes = 0;
free(_analogueInputBuffer); return;
free(_analogueInputStates); }
free(_analoguePinMap);
} }
_analogueInputStates = (uint8_t*) calloc(analogueBytesNeeded, 1);
_analogueInputBuffer = (uint8_t*) calloc(analogueBytesNeeded, 1);
_analoguePinMap = (uint8_t*) calloc(_numAnaloguePins, 1);
_analoguePinBytes = analogueBytesNeeded;
} }
} else { if (_numAnaloguePins>0) {
DIAG(F("EX-IOExpander I2C:%s ERROR configuring device"), _I2CAddress.toString()); size_t analogueBytesNeeded = _numAnaloguePins * 2;
_deviceState = DEVSTATE_FAILED; if (_analoguePinBytes < analogueBytesNeeded) {
return; // Free any existing buffers and allocate new ones.
} if (_analoguePinBytes > 0) {
} free(_analogueInputBuffer);
// We now need to retrieve the analogue pin map free(_analogueInputStates);
if (status == I2C_STATUS_OK) { free(_analoguePinMap);
}
_analogueInputStates = (uint8_t*) calloc(analogueBytesNeeded, 1);
_analogueInputBuffer = (uint8_t*) calloc(analogueBytesNeeded, 1);
_analoguePinMap = (uint8_t*) calloc(_numAnaloguePins, 1);
if (_analogueInputStates != NULL &&
_analogueInputBuffer != NULL &&
_analoguePinMap != NULL) {
_analoguePinBytes = analogueBytesNeeded;
} else {
DIAG(F("EX-IOExpander I2C:%s ERROR alloc analog pin bytes"), _I2CAddress.toString());
_deviceState = DEVSTATE_FAILED;
_analoguePinBytes = 0;
return;
}
}
}
} else {
DIAG(F("EX-IOExpander I2C:%s ERROR configuring device"), _I2CAddress.toString());
_deviceState = DEVSTATE_FAILED;
return;
}
}
// We now need to retrieve the analogue pin map if there are analogue pins
if (status == I2C_STATUS_OK && _numAnaloguePins>0) {
commandBuffer[0] = EXIOINITA; commandBuffer[0] = EXIOINITA;
status = I2CManager.read(_I2CAddress, _analoguePinMap, _numAnaloguePins, commandBuffer, 1); status = I2CManager.read(_I2CAddress, _analoguePinMap, _numAnaloguePins, commandBuffer, 1);
} }
@ -239,7 +259,7 @@ private:
// If we're not doing anything now, check to see if a new input transfer is due. // If we're not doing anything now, check to see if a new input transfer is due.
if (_readState == RDS_IDLE) { if (_readState == RDS_IDLE) {
if (currentMicros - _lastDigitalRead > _digitalRefresh) { // Delay for digital read refresh if (_numDigitalPins>0 && currentMicros - _lastDigitalRead > _digitalRefresh) { // Delay for digital read refresh
// Issue new read request for digital states. As the request is non-blocking, the buffer has to // Issue new read request for digital states. As the request is non-blocking, the buffer has to
// be allocated from heap (object state). // be allocated from heap (object state).
_readCommandBuffer[0] = EXIORDD; _readCommandBuffer[0] = EXIORDD;
@ -247,7 +267,7 @@ private:
// non-blocking read // non-blocking read
_lastDigitalRead = currentMicros; _lastDigitalRead = currentMicros;
_readState = RDS_DIGITAL; _readState = RDS_DIGITAL;
} else if (currentMicros - _lastAnalogueRead > _analogueRefresh) { // Delay for analogue read refresh } else if (_numAnaloguePins>0 && currentMicros - _lastAnalogueRead > _analogueRefresh) { // Delay for analogue read refresh
// Issue new read for analogue input states // Issue new read for analogue input states
_readCommandBuffer[0] = EXIORDAN; _readCommandBuffer[0] = EXIORDAN;
I2CManager.read(_I2CAddress, _analogueInputBuffer, I2CManager.read(_I2CAddress, _analogueInputBuffer,
@ -362,14 +382,14 @@ private:
uint8_t _minorVer = 0; uint8_t _minorVer = 0;
uint8_t _patchVer = 0; uint8_t _patchVer = 0;
uint8_t* _digitalInputStates; uint8_t* _digitalInputStates = NULL;
uint8_t* _analogueInputStates; uint8_t* _analogueInputStates = NULL;
uint8_t* _analogueInputBuffer; // buffer for I2C input transfers uint8_t* _analogueInputBuffer = NULL; // buffer for I2C input transfers
uint8_t _readCommandBuffer[1]; uint8_t _readCommandBuffer[1];
uint8_t _digitalPinBytes = 0; // Size of allocated memory buffer (may be longer than needed) uint8_t _digitalPinBytes = 0; // Size of allocated memory buffer (may be longer than needed)
uint8_t _analoguePinBytes = 0; // Size of allocated memory buffers (may be longer than needed) uint8_t _analoguePinBytes = 0; // Size of allocated memory buffer (may be longer than needed)
uint8_t* _analoguePinMap; uint8_t* _analoguePinMap = NULL;
I2CRB _i2crb; I2CRB _i2crb;
enum {RDS_IDLE, RDS_DIGITAL, RDS_ANALOGUE}; // Read operation states enum {RDS_IDLE, RDS_DIGITAL, RDS_ANALOGUE}; // Read operation states

View File

@ -1,77 +1,39 @@
# What is DCC++ EX? # What is DCC-EX?
DCC++ EX is the organization maintaining several codebases that together represent a fully open source DCC system. Currently, this includes the following: DCC-EX is a team of dedicated enthusiasts producing open source DCC & DC solutions for you to run your complete model railroad layout. Our easy to use, do-it-yourself, and free open source products run on off-the-shelf Arduino technology and are supported by numerous third party hardware and apps like JMRI, Engine Driver, wiThrottle, Rocrail and more.
* [CommandStation-EX](https://github.com/DCC-EX/CommandStation-EX/releases) - the latest take on the DCC++ command station for controlling your trains. Runs on an Arduino board, and includes advanced features such as a WiThrottle server implementation, turnout operation, general purpose inputs and outputs (I/O), and JMRI integration. Currently, our products include the following:
* [exWebThrottle](https://github.com/DCC-EX/exWebThrottle) - a simple web based controller for your DCC++ command station.
* [BaseStation-installer](https://github.com/DCC-EX/BaseStation-Installer) - an installer executable that takes care of downloading and installing DCC++ firmware onto your hardware setup.
* [BaseStation-Classic](https://github.com/DCC-EX/BaseStation-Classic) - the original DCC++ software, packaged in a stable release. No active development, bug fixes only.
A basic DCC++ EX hardware setup can use easy to find, widely avalable Arduino boards that you can assemble yourself. * [EX-CommandStation](https://github.com/DCC-EX/CommandStation-EX/releases)
* [EX-WebThrottle](https://github.com/DCC-EX/exWebThrottle)
Both CommandStation-EX and BaseStation-Classic support much of the NMRA Digital Command Control (DCC) [standards](http://www.nmra.org/dcc-working-group "NMRA DCC Working Group"), including: * [EX-Installer](https://github.com/DCC-EX/EX-Installer)
* [EX-MotoShield8874](https://dcc-ex.com/reference/hardware/motorboards/ex-motor-shield-8874.html#gsc.tab=0)
* simultaneous control of multiple locomotives * [EX-DCCInspector](https://github.com/DCC-EX/DCCInspector-EX)
* 2-byte and 4-byte locomotive addressing * [EX-Toolbox](https://github.com/DCC-EX/EX-Toolbox)
* 28 or 128-step speed throttling * [EX-Turntable](https://github.com/DCC-EX/EX-Turntable)
* Activate/de-activate all accessory function addresses 0-2048 * [EX-IOExpander](https://github.com/DCC-EX/EX-IOExpander)
* Control of all cab functions F0-F28 and F29-F68 * [EX-FastClock](https://github.com/DCC-EX/EX-FastClock)
* Main Track: Write configuration variable bytes and set/clear specific configuration variable (CV) bits (aka Programming on Main or POM) * [DCCEXProtocol](https://github.com/DCC-EX/DCCEXProtocol)
* Programming Track: Same as the main track with the addition of reading configuration variable bytes
* And many more custom features. see [What's new in CommandStation-EX?](#whats-new-in-commandstation-ex)
Details of these projects can be found on [our web site](https://dcc-ex.com/).
# Whats in this Repository? # Whats in this Repository?
This repository, CommandStation-EX, contains a complete DCC++ EX Commmand Station sketch designed for compiling and uploading into an Arduino Uno, Mega, or Nano. This repository, CommandStation-EX, contains a complete DCC-EX *EX-CommmandStation* sketch designed for compiling and uploading into an Arduino Uno, Mega, or Nano.
To utilize this sketch, you can use the following: To utilize this sketch, you can use the following:
1. (beginner) our [automated installer](https://github.com/DCC-EX/BaseStation-Installer) 1. (recommended for all levels of user) our [automated installer](https://github.com/DCC-EX/EX-Installer)
2. (intermediate) download the latest version from the [releases page](https://github.com/DCC-EX/CommandStation-EX/releases) 2. (intermediate) download the latest version from the [releases page](https://github.com/DCC-EX/CommandStation-EX/releases)
3. (advanced) use git clone on this repository 3. (advanced) use git clone on this repository
Not using the installer? Open the file "CommandStation-EX.ino" in the Refer to [our web site](https://https://dcc-ex.com/ex-commandstation/get-started/index.html#/) for the hardware required for this project.
Arduino IDE. Please do not rename the folder containing the sketch
code, nor add any files in that folder. The Arduino IDE relies on the
structure and name of the folder to properly display and compile the
code. Rename or copy config.example.h to config.h. If you do not have
the standard setup, you must edit config.h according to the help texts
in config.h.
## What's new in CommandStation-EX? **We seriously recommend using the EX-Installer**, however if you choose not to use the installer...
* WiThrottle server built in. Connect Engine Driver or WiThrottle clients directly to your Command Station (or through JMRI as before) * Open the file ``CommandStation-EX.ino`` in the Arduino IDE or Visual Studio Code (VSC). Please do not rename the folder containing the sketch code, nor add any files in that folder. The Arduino IDE relies on the structure and name of the folder to properly display and compile the code.
* WiFi and Ethernet shield support * Rename or copy ``config.example.h`` to ``config.h``.
* No more jumpers or soldering! * You must edit ``config.h`` according to the help texts in ``config.h``.
* Direct support for all the most popular motor control boards including single pin (Arduino) or dual pin (IBT_2) type PWM inputs without the need for an adapter circuit
* I2C Display support (LCD and OLED)
* Improved short circuit detection and automatic reset from an overload
* Current reading, sensing and ACK detection settings in milliAmps instead of just pin readings
* Improved adherence to the NMRA DCC specification
* Complete support for all the old commands and front ends like JMRI
* Railcom cutout (beta)
* Simpler, modular, faster code with an API Library for developers for easy expansion
* New features and functions in JMRI
* Ability to join MAIN and PROG tracks into one MAIN track to run your locos
* "Drive-Away" feature - Throttles with support, like Engine Driver, can allow a loco to be programmed on a usable, electrically isolated programming track and then drive off onto the main track
* Diagnostic commands to test decoders that aren't reading or writing correctly
* Support for Uno, Nano, Mega, Nano Every and Teensy microcontrollers
* User Functions: Filter regular commands (like a turnout or output command) and pass it to your own function or accessory
* Support for LCN (layout control nodes)
* mySetup.h file that acts like an Autoexec.Bat command to send startup commands to the CS
* High Accuracty Waveform option for rock steady DCC signals
* New current response outputs current in mA, overlimit current, and maximum board capable current. Support for new current meter in JMRI
* USB Browser based EX-WebThrottle
* New, simpler, function control command
* Number of locos discovery command `<#>`
* Emergency stop command <!>
* Release cabs from memory command <-> all cabs, <- CAB> for just one loco address
* Automatic slot (register) management
* Automation (coming soon)
NOTE: DCC-EX is a major rewrite to the code. We started over and rebuilt it from the ground up! For what that means, you can read [HERE](https://dcc-ex.com/about/rewrite.html).
# More information # More information
You can learn more at the [DCC++ EX website](https://dcc-ex.com/) You can learn more at the [DCC-EX website](https://dcc-ex.com/)
- November 14, 2020

View File

@ -3,7 +3,10 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "5.0.7" #define VERSION "5.0.9"
// 5.0.9 - EX-IOExpander bug fix for memory allocation
// - EX-IOExpander bug fix to allow for devices with no analogue or no digital pins
// 5.0.8 - Bugfix: Do not crash on turnouts without description
// 5.0.7 - Only flag 2.2.0.0-dev as broken, not 2.2.0.0 // 5.0.7 - Only flag 2.2.0.0-dev as broken, not 2.2.0.0
// 5.0.6 - Bugfix lost TURNOUTL description // 5.0.6 - Bugfix lost TURNOUTL description
// 5.0.5 - Bugfix version detection logic and better message // 5.0.5 - Bugfix version detection logic and better message