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

<V> commands

UNTESTED
This commit is contained in:
Asbelos 2020-09-18 00:04:42 +01:00
parent f964308994
commit 59febed37d
4 changed files with 72 additions and 0 deletions

51
DCC.cpp
View File

@ -221,6 +221,22 @@ const ackOp PROGMEM WRITE_BIT1_PROG[] = {
FAIL // callback (-1)
};
const ackOp PROGMEM VERIFY_BIT0_PROG[] = {
BASELINE,
V0, WACK, // validate bit is 0
ITC0, // if acked, callback(0)
V1, WACK, // validate bit is 1
ITC1,
FAIL // callback (-1)
};
const ackOp PROGMEM VERIFY_BIT1_PROG[] = {
BASELINE,
V1, WACK, // validate bit is 1
ITC1, // if acked, callback(1)
V0, WACK,
ITC0,
FAIL // callback (-1)
};
const ackOp PROGMEM READ_BIT_PROG[] = {
BASELINE,
@ -239,6 +255,30 @@ const ackOp PROGMEM WRITE_BYTE_PROG[] = {
FAIL // callback (-1)
};
const ackOp PROGMEM VERIFY_BYTE_PROG[] = {
BASELINE,
VB,WACK, // validate byte
ITCB, // if ok callback value
STARTMERGE, //clear bit and byte values ready for merge pass
// each bit is validated against 0 and the result inverted in MERGE
// this is because there tend to be more zeros in cv values than ones.
// There is no need for one validation as entire byte is validated at the end
V0, WACK, MERGE, // read and merge first tested bit (7)
ITSKIP, // do small excursion if there was no ack
SETBIT,(ackOp)7,
V1, WACK, NAKFAIL, // test if there is an ack on the inverse of this bit (7)
SETBIT,(ackOp)6, // and abort whole test if not else continue with bit (6)
SKIPTARGET,
V0, WACK, MERGE, // read and merge second tested bit (6)
V0, WACK, MERGE, // read and merge third tested bit (5) ...
V0, WACK, MERGE,
V0, WACK, MERGE,
V0, WACK, MERGE,
V0, WACK, MERGE,
V0, WACK, MERGE,
VB, WACK, ITCB, // verify merged byte and return it if acked ok
FAIL };
const ackOp PROGMEM READ_CV_PROG[] = {
BASELINE,
@ -268,6 +308,7 @@ const ackOp PROGMEM LOCO_ID_PROG[] = {
SETCV,(ackOp)29,
SETBIT,(ackOp)5,
V0, WACK, ITSKIP, // Skip to SKIPTARGET if bit 5 of CV29 is zero
V1, WACK, NAKFAIL, // fast fail if no loco on track
// Long locoid
SETCV, (ackOp)17, // CV 17 is part of locoid
STARTMERGE,
@ -329,6 +370,16 @@ void DCC::writeCVBit(int cv, byte bitNum, bool bitValue, ACK_CALLBACK callback,
else ackManagerSetup(cv, bitNum, bitValue?WRITE_BIT1_PROG:WRITE_BIT0_PROG, callback, blocking);
}
void DCC::verifyCVByte(int cv, byte byteValue, ACK_CALLBACK callback, bool blocking) {
ackManagerSetup(cv, byteValue, VERIFY_BYTE_PROG, callback, blocking);
}
void DCC::verifyCVBit(int cv, byte bitNum, bool bitValue, ACK_CALLBACK callback, bool blocking) {
if (bitNum >= 8) callback(-1);
else ackManagerSetup(cv, bitNum, bitValue?VERIFY_BIT1_PROG:VERIFY_BIT0_PROG, callback, blocking);
}
void DCC::readCVBit(int cv, byte bitNum, ACK_CALLBACK callback, bool blocking) {
if (bitNum >= 8) callback(-1);

2
DCC.h
View File

@ -81,6 +81,8 @@ class DCC {
static void readCVBit(int cv, byte bitNum, ACK_CALLBACK callback, bool blocking=false); // -1 for error
static void writeCVByte(int cv, byte byteValue, ACK_CALLBACK callback, bool blocking=false) ;
static void writeCVBit(int cv, byte bitNum, bool bitValue, ACK_CALLBACK callback, bool blocking=false);
static void verifyCVByte(int cv, byte byteValue, ACK_CALLBACK callback, bool blocking=false) ;
static void verifyCVBit(int cv, byte bitNum, bool bitValue, ACK_CALLBACK callback, bool blocking=false);
static void getLocoId(ACK_CALLBACK callback, bool blocking=false);

View File

@ -221,11 +221,19 @@ void DCCEXParser::parse(Print * stream, byte *com, bool blocking) {
DCC::writeCVByte(p[0],p[1],callback_W,blocking);
return;
case 'V': // VERIFY CV ON PROG <V CV VALUE> <V CV BIT 0|1>
if (!stashCallback(stream,p)) break;
if (params==2) DCC::verifyCVByte(p[0],p[1],callback_Vbyte,blocking);
else if (params==3) DCC::verifyCVBit(p[0],p[1],p[2],callback_Vbit,blocking);
else break;
return;
case 'B': // WRITE CV BIT ON PROG <B CV BIT VALUE CALLBACKNUM CALLBACKSUB>
if (!stashCallback(stream,p)) break;
DCC::writeCVBit(p[0],p[1],p[2],callback_B,blocking);
return;
case 'R': // READ CV ON PROG <R CV CALLBACKNUM CALLBACKSUB>
if (!stashCallback(stream,p)) break;
DCC::readCV(p[0],callback_R,blocking);
@ -510,6 +518,15 @@ void DCCEXParser::callback_B(int result) {
StringFormatter::send(stashStream,F("<r%d|%d|%d %d %d>"), stashP[3],stashP[4], stashP[0],stashP[1],result==1?stashP[2]:-1);
stashBusy=false;
}
void DCCEXParser::callback_Vbit(int result) {
StringFormatter::send(stashStream,F("<v %d %d %d>"), stashP[0], stashP[1],result);
stashBusy=false;
}
void DCCEXParser::callback_Vbyte(int result) {
StringFormatter::send(stashStream,F("<v %d %d>"), stashP[0],result);
stashBusy=false;
}
void DCCEXParser::callback_R(int result) {
StringFormatter::send(stashStream,F("<r%d|%d|%d %d>"),stashP[1],stashP[2],stashP[0],result);
stashBusy=false;

View File

@ -55,6 +55,8 @@ struct DCCEXParser
static void callback_W(int result);
static void callback_B(int result);
static void callback_R(int result);
static void callback_Vbit(int result);
static void callback_Vbyte(int result);
static FILTER_CALLBACK filterCallback;
static void funcmap(int cab, byte value, byte fstart, byte fstop);