mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-04-02 19:50:13 +02:00
Advanced zzparse diagnostics
This commit is contained in:
parent
b840aee21e
commit
2b82e65978
@ -137,7 +137,7 @@ ZZ(T,id,DCC,nn) CHECK(DCCTurnout::create(id, (nn-1)/4+1, (nn-1)%4))
|
||||
ZZ(T,id,addr,subadd) CHECK(DCCTurnout::create(id, addr, subadd))
|
||||
ZZ(T,id,pin,low,high) CHECK(ServoTurnout::create(id, (VPIN)pin,low,high,1))
|
||||
ZZ(S,id,pin,pullup) CHECK(Sensor::create(id,pin,pullup))
|
||||
ZZ(S,id) CHECK(Sensor::remove(p[0]))
|
||||
ZZ(S,id) CHECK(Sensor::remove(id))
|
||||
ZZ(S) for (auto *tt = Sensor::firstSensor; tt; tt = tt->nextSensor) {
|
||||
REPLY("<Q %d %d %d>\n", tt->data.snum, tt->data.pin, tt->data.pullUp)
|
||||
}
|
||||
@ -238,7 +238,7 @@ ZZ(I,id,EXTT,vpin,home) // <I id EXTT vpin home> create an EXTT turntable
|
||||
|
||||
|
||||
ZZ(I,id,ADD,position,value,angle) // <I id ADD position value angle> add a position
|
||||
auto tto = Turntable::get(p[0]);
|
||||
auto tto = Turntable::get(id);
|
||||
// tto must exist, no more than 48 positions, angle 0 - 3600
|
||||
CHECK(tto && position <= 48 && angle >=0 && angle <= 3600)
|
||||
tto->addPosition(id,value,angle);
|
||||
@ -342,7 +342,7 @@ ZZ(D,ACK,RETRY,value) DCCACK::setAckRetry(value); LCD(1, F(
|
||||
ZZ(C,WIFI,marker1,ssid,marker2,password)
|
||||
// <C WIFI SSID PASSWORD>
|
||||
CHECK(marker1==0x7777 && marker2==0x7777)
|
||||
WifiESP::setup((const char*)(com + p[2]), (const char*)(com + p[4]), WIFI_HOSTNAME, IP_PORT, WIFI_CHANNEL, WIFI_FORCE_AP);
|
||||
WifiESP::setup((const char*)(com + ssid), (const char*)(com + password), WIFI_HOSTNAME, IP_PORT, WIFI_CHANNEL, WIFI_FORCE_AP);
|
||||
#endif
|
||||
|
||||
ZZ(o,vpin) IODevice::write(abs(vpin),vpin>0);
|
||||
@ -379,7 +379,7 @@ ZZ(a,linearaddress,activate)
|
||||
DCC::setAccessory((linearaddress - 1) / 4 + 1,(linearaddress - 1) % 4 ,activate ^ accessoryCommandReverse);
|
||||
ZZ(A,address,value) DCC::setExtendedAccessory(address,value);
|
||||
|
||||
ZZ(w,cab,cv,value) DCC::writeCVByteMain(p[0], p[1], p[2]);
|
||||
ZZ(w,cab,cv,value) DCC::writeCVByteMain(cab,cv,value);
|
||||
ZZ(r,cab,cv)
|
||||
CHECK(DCCWaveform::isRailcom())
|
||||
EXPECT_CALLBACK
|
||||
|
@ -328,12 +328,14 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||
if (TrackManager::parseEqualSign(stream, params, p))
|
||||
return;
|
||||
|
||||
|
||||
matchedCommandFormat = F("none");
|
||||
checkFailedFormat = matchedCommandFormat;
|
||||
if (execute(com,stream, opcode, params, p, ringStream)) return;
|
||||
|
||||
// TODO magnificent diagnostics
|
||||
StringFormatter::send(stream, F("<X>\n"), opcode);
|
||||
if (opcode >= ' ' && opcode <= '~') {
|
||||
// TODO magnificent diagnostics
|
||||
StringFormatter::send(stream, F("<X>\n"));
|
||||
DIAG(F("Command format <%<> failed CHECK(%S)\n"), matchedCommandFormat, checkFailedFormat);
|
||||
if (opcode >= ' ' && opcode <= '~') {
|
||||
DIAG(F("Opcode=%c params=%d"), opcode, params);
|
||||
for (int i = 0; i < params; i++)
|
||||
DIAG(F("p[%d]=%d (0x%x)"), i, p[i], p[i]);
|
||||
@ -373,11 +375,9 @@ bool DCCEXParser::funcmap(int16_t cab, byte value, byte fstart, byte fstop)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DCC_ACCESSORY_COMMAND_REVERSE
|
||||
const bool accessoryCommandReverse = true;
|
||||
#else
|
||||
const bool accessoryCommandReverse = false;
|
||||
#endif
|
||||
const FSH* DCCEXParser::matchedCommandFormat=nullptr;
|
||||
const FSH* DCCEXParser::checkFailedFormat=nullptr;
|
||||
|
||||
|
||||
// Having broken the command into opcode and parameters, we now execute the command
|
||||
// The actual commands and their parameter mappings are in DCCEXCommands.h
|
||||
|
@ -42,7 +42,13 @@ struct DCCEXParser
|
||||
static const int MAX_COMMAND_PARAMS=10; // Must not exceed this
|
||||
|
||||
private:
|
||||
|
||||
static const FSH * matchedCommandFormat;
|
||||
static const FSH * checkFailedFormat;
|
||||
#ifdef DCC_ACCESSORY_COMMAND_REVERSE
|
||||
static const bool accessoryCommandReverse = true;
|
||||
#else
|
||||
static const bool accessoryCommandReverse = false;
|
||||
#endif
|
||||
static const int16_t MAX_BUFFER=50; // longest command sent in
|
||||
static int16_t splitValues( int16_t result[MAX_COMMAND_PARAMS], byte * command, bool usehex);
|
||||
static bool execute(byte * command, Print * stream, byte opcode, byte params, int16_t p[], RingStream * ringStream);
|
||||
|
@ -24,11 +24,11 @@
|
||||
#define Z8(op,_1,_2,_3,_4,_5,_6,_7) ZPREP(op,7) ZZZ(0,_1) ZZZ(1,_2) ZZZ(2,_3) ZZZ(3,_4) ZZZ(4,_5) ZZZ(5,_6) ZZZ(6,_7)
|
||||
|
||||
#define ZRIP(count) CONCAT(Z,count)
|
||||
#define ZZ(...) ZRIP(FOR_EACH_NARG(__VA_ARGS__))(__VA_ARGS__)
|
||||
#define ZZ(...) ZRIP(FOR_EACH_NARG(__VA_ARGS__))(__VA_ARGS__) matchedCommandFormat = F( #__VA_ARGS__);
|
||||
|
||||
#define ZZBEGIN if (false) {
|
||||
#define ZZEND return true; } return false;
|
||||
#define CHECK(x) if (!(x)) return false;
|
||||
#define CHECK(x) if (!(x)) { checkFailedFormat=F(#x); return false;}
|
||||
#define REPLY(format,...) StringFormatter::send(stream,F(format), ##__VA_ARGS__);
|
||||
#define EXPECT_CALLBACK CHECK(stashCallback(stream, p, ringStream))
|
||||
|
||||
|
@ -123,6 +123,7 @@ void StringFormatter::send2(Print * stream,const FSH* format, va_list args) {
|
||||
case 's': stream->print(va_arg(args, char*)); break;
|
||||
case 'e': printEscapes(stream,va_arg(args, char*)); break;
|
||||
case 'E': printEscapes(stream,(const FSH*)va_arg(args, char*)); break;
|
||||
case '<': printCmdFormat(stream,(const FSH*)va_arg(args, char*)); break;
|
||||
case 'S':
|
||||
{
|
||||
const FSH* flash= (const FSH*)va_arg(args, char*);
|
||||
@ -202,15 +203,27 @@ void StringFormatter::printEscapes(Print * stream,char * input) {
|
||||
|
||||
void StringFormatter::printEscapes(Print * stream, const FSH * input) {
|
||||
|
||||
if (!stream) return;
|
||||
char* flash=(char*)input;
|
||||
for(int i=0; ; ++i) {
|
||||
char c=GETFLASH(flash+i);
|
||||
printEscape(stream,c);
|
||||
if (c=='\0') return;
|
||||
if (!stream) return;
|
||||
char* flash=(char*)input;
|
||||
for(int i=0; ; ++i) {
|
||||
char c=GETFLASH(flash+i);
|
||||
printEscape(stream,c);
|
||||
if (c=='\0') return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringFormatter::printCmdFormat(Print * stream, const FSH * input) {
|
||||
|
||||
if (!stream) return;
|
||||
char* flash=(char*)input;
|
||||
for(int i=0; ; ++i) {
|
||||
char c=GETFLASH(flash+i);
|
||||
if (c=='\0') return;
|
||||
if (c==',') c=' ';
|
||||
stream->write(c);
|
||||
}
|
||||
}
|
||||
|
||||
void StringFormatter::printEscape( char c) {
|
||||
printEscape(&USB_SERIAL,c);
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class StringFormatter
|
||||
|
||||
static void printEscapes(Print * serial,char * input);
|
||||
static void printEscapes(Print * serial,const FSH* input);
|
||||
static void printCmdFormat(Print * serial,const FSH* input);
|
||||
static void printEscape(Print * serial, char c);
|
||||
|
||||
// DIAG support
|
||||
|
Loading…
Reference in New Issue
Block a user