1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-23 16:16:13 +01:00

Compare commits

..

3 Commits

Author SHA1 Message Date
Harald Barth
bbba53f3d1 version 2024-04-01 11:59:16 +02:00
Harald Barth
605d5826dc make Z21 support dependent on ESP32 to compile on all platforms 2024-04-01 11:57:57 +02:00
Harald Barth
e075df7164 Z21 error fix for turnout feedback 2024-04-01 11:10:54 +02:00
8 changed files with 70 additions and 27 deletions

View File

@ -31,7 +31,10 @@
#include "DCC.h"
#include "TrackManager.h"
#include "StringFormatter.h"
#ifdef Z21_PROTOCOL
#include "Z21Throttle.h"
#endif
// variables to hold clock time
int16_t lastclocktime;
@ -150,7 +153,9 @@ void CommandDistributor::broadcastToClients(clientType type) {
// Public broadcast functions below
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
#ifdef Z21_PROTOCOL
Z21Throttle::broadcastNotifySensor(id, on);
#endif
broadcastReply(COMMAND_TYPE, F("<%c %d>\n"), on?'Q':'q', id);
}
@ -158,7 +163,9 @@ void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
// The string below contains serial and Withrottle protocols which should
// be safe for both types.
#ifdef Z21_PROTOCOL
Z21Throttle::broadcastNotifyTurnout(id, isClosed);
#endif
broadcastReply(COMMAND_TYPE, F("<H %d %d>\n"),id, !isClosed);
#ifdef CD_HANDLE_RING
broadcastReply(WITHROTTLE_TYPE, F("PTA%c%d\n"), isClosed?'2':'4', id);

View File

@ -1 +1 @@
#define GITHUB_SHA "devel-z21-202403251406Z"
#define GITHUB_SHA "devel-z21-202404011058Z"

View File

@ -30,7 +30,10 @@
#include "RingStream.h"
#include "CommandDistributor.h"
#include "WiThrottle.h"
#ifdef Z21_PROTOCOL
#include "Z21Throttle.h"
#endif
/*
#include "soc/rtc_wdt.h"
#include "esp_task_wdt.h"
@ -258,10 +261,13 @@ bool WifiESP::setup(const char *SSid,
DIAG(F("Wifi setup failed to add withrottle service to mDNS"));
}
// server for WiThrottle and DCCEX protocol started here
server = new WiFiServer(port); // start listening on tcp port
server->begin();
// server started here
#ifdef Z21_PROTOCOL
// server for Z21 Protocol started here
Z21Throttle::setup(localIP, Z21_UDPPORT);
#endif
#ifdef WIFI_TASK_ON_CORE0
//start loop task
@ -336,7 +342,9 @@ void WifiESP::loop() {
} // all clients
WiThrottle::loop(outboundRing);
#ifdef Z21_PROTOCOL
Z21Throttle::loop();
#endif
// something to write out?
clientId=outboundRing->read();

View File

@ -20,6 +20,7 @@
*/
#include <Arduino.h>
#include "defines.h"
#ifdef Z21_PROTOCOL
#include <WiFi.h>
#include "Z21Throttle.h"
#include "DCC.h"
@ -417,43 +418,49 @@ void Z21Throttle::notifyLocoInfo(byte inMSB, byte inLSB) {
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_LOCO_INFO, Z21Throttle::replyBuffer, 9, false);
}
// This variant is called from the broadcast function when turnouts change
// from the "inside" where we know the turnout state
void Z21Throttle::notifyTurnoutInfo(uint16_t addr, bool isClosed) {
notifyTurnoutInfo((byte)((addr-1) >> 8), (byte)((addr-1) & 0xFF), isClosed);
}
// This variant is called from the Xnet protocol when the client queries
// the state of a turnout (which may or may not exist)
void Z21Throttle::notifyTurnoutInfo(byte inMSB, byte inLSB) {
uint16_t addr = (inMSB << 8) + inLSB + 1;
Turnout *tt = Turnout::get(addr);
if (tt) {
notifyTurnoutInfo(inMSB, inLSB, tt->isClosed());
return;
}
// if the tt does not exist we fall through with replyBuffer set to invalid
Z21Throttle::replyBuffer[0] = inMSB; // turnout address msb
Z21Throttle::replyBuffer[1] = inLSB; // turnout address lsb
Z21Throttle::replyBuffer[2] = B00000011; // 000000ZZ ZZ: 00=not-switched 01=pos1 10=pos2 11=invalid
if (Diag::Z21THROTTLE)
DIAG(F("Z21 Throttle %d : Turnoutinfo %d (invalid)"), clientid, addr);
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_TURNOUT_INFO, Z21Throttle::replyBuffer, 3, false);
}
// This variant is called when we know that turnout exists and it's state.
void Z21Throttle::notifyTurnoutInfo(byte inMSB, byte inLSB, bool isClosed) {
Z21Throttle::replyBuffer[0] = inMSB;
Z21Throttle::replyBuffer[1] = inLSB;
char c;
Z21Throttle::replyBuffer[0] = (byte)(addr >> 8);
Z21Throttle::replyBuffer[1] = (byte)(addr & 0xFF);
if (isClosed) {
Z21Throttle::replyBuffer[2] = B00000010;
Z21Throttle::replyBuffer[2] = B00000010; // 000000ZZ ZZ: 00=not-switched 01=pos1 10=pos2 11=invalid
c = 'c';
} else {
Z21Throttle::replyBuffer[2] = B00000001;
c = 't';
}
if (Diag::Z21THROTTLE)
if (Diag::Z21THROTTLE) {
uint16_t addr = (inMSB << 8) + inLSB + 1;
DIAG(F("Z21 Throttle %d : Turnoutinfo %d %c"), clientid, addr, c);
}
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_TURNOUT_INFO, Z21Throttle::replyBuffer, 3, false);
}
void Z21Throttle::notifyTurnoutInfo(byte inMSB, byte inLSB) {
Z21Throttle::replyBuffer[0] = inMSB; // turnout address msb
Z21Throttle::replyBuffer[1] = inLSB; // turnout address lsb
Z21Throttle::replyBuffer[2] = B00000011; // 000000ZZ ZZ : 00 not switched 01 pos1 10 pos2 11 invalid
char c = '?';
uint16_t addr = (inMSB << 8) + inLSB + 1;
Turnout *tt = Turnout::get(addr);
if (tt) { // if the tt does not exist we fall through with replyBuffer set to invalid
if (tt->isClosed()) {
Z21Throttle::replyBuffer[2] = B00000010;
c = 'c';
} else {
Z21Throttle::replyBuffer[2] = B00000001;
c = 't';
}
}
if (Diag::Z21THROTTLE)
DIAG(F("Z21 Throttle %d : Turnoutinfo %d %c"), clientid, addr, c);
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_TURNOUT_INFO, Z21Throttle::replyBuffer, 3, false);
}
void Z21Throttle::notifySensor(uint16_t addr) {
Sensor *s = Sensor::get(addr);
if (s) {
@ -975,3 +982,4 @@ bool Z21Throttle::parse(byte *networkPacket, int len) {
// if we get here, we did parse one or several xbus packets inside USB packets
return true;
}
#endif // Z21_PROTOCOL

View File

@ -19,6 +19,9 @@
#ifndef Z21Throttle_h
#define Z21Throttle_h
#include "defines.h"
#ifdef Z21_PROTOCOL
//#include "CircularBuffer.hpp"
#include "NetworkClientUDP.h"
@ -125,6 +128,7 @@ class Z21Throttle {
void notifyLocoInfo(byte inMSB, byte inLSB);
void notifyTurnoutInfo(uint16_t addr, bool isClosed);
void notifyTurnoutInfo(byte inMSB, byte inLSB);
void notifyTurnoutInfo(byte inMSB, byte inLSB, bool isClosed);
void notifySensor(uint16_t addr);
void notifySensor(uint16_t addr, bool state);
void notifyLocoMode(byte inMSB, byte inLSB);
@ -216,4 +220,5 @@ class Z21Throttle {
#define LAN_X_DB0_CV_NACK 0x13
#endif // Z21PROTOCOL
#endif

View File

@ -300,6 +300,12 @@ The configuration file for DCC-EX Command Station
//
//#define BOOSTER_INPUT 26
// Z21 protocol support
// On ESP32 you have the possibility to use the Z21 app
// and other devices that use the Z21 protocol over IP/UDP.
//
//#define Z21_PROTOCOL
// SABERTOOTH
//
// This is a very special option and only useful if you happen to have a

View File

@ -157,6 +157,14 @@
#define CPU_TYPE_ERROR
#endif
// Only ESP32 does support the Z21 protocol currently
#ifndef ARDUINO_ARCH_ESP32
#ifdef Z21_PROTOCOL
#warning "Z21 protocol can not be used on this platform, disabling"
#undef Z21_PROTOCOL
#endif
#endif
// replace board type if provided by compiler
#ifdef BOARD_NAME
#undef ARDUINO_TYPE

View File

@ -4,6 +4,7 @@
#include "StringFormatter.h"
#define VERSION "5.X.Y"
// Z21 error fix for turnout feedback
// Z21 add turnout and sensor broadcasts
// Z21: report the (unchanged) loco mode back after every attempted change
// Add turnout functionality to Z21