mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 12:51:24 +01:00
<V> commands
UNTESTED
This commit is contained in:
parent
f964308994
commit
59febed37d
51
DCC.cpp
51
DCC.cpp
@ -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
2
DCC.h
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user