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

ACK pulse timins refer @haba

This commit is contained in:
Asbelos 2020-06-09 08:35:14 +01:00
parent f8f4268a48
commit 50cbcabe00
2 changed files with 27 additions and 10 deletions

28
DCC.cpp
View File

@ -299,6 +299,7 @@ int DCC::ackManagerCv;
byte DCC::ackManagerBitNum; byte DCC::ackManagerBitNum;
bool DCC::ackReceived; bool DCC::ackReceived;
int DCC::ackTriggerMilliamps; int DCC::ackTriggerMilliamps;
long DCC::ackPulseStart;
ACK_CALLBACK DCC::ackManagerCallback; ACK_CALLBACK DCC::ackManagerCallback;
@ -337,6 +338,7 @@ void DCC::ackManagerLoop() {
byte instruction = WRITE_BIT | (opcode==W1 ? BIT_ON : BIT_OFF) | ackManagerBitNum; byte instruction = WRITE_BIT | (opcode==W1 ? BIT_ON : BIT_OFF) | ackManagerBitNum;
byte message[] = {cv1(BIT_MANIPULATE, ackManagerCv), cv2(ackManagerCv), instruction }; byte message[] = {cv1(BIT_MANIPULATE, ackManagerCv), cv2(ackManagerCv), instruction };
DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 6); DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 6);
ackPulseStart=0;
} }
break; break;
@ -345,6 +347,7 @@ void DCC::ackManagerLoop() {
if (resets<RESET_MIN) return; // try later if (resets<RESET_MIN) return; // try later
byte message[] = {cv1(WRITE_BYTE, ackManagerCv), cv2(ackManagerCv), ackManagerByte}; byte message[] = {cv1(WRITE_BYTE, ackManagerCv), cv2(ackManagerCv), ackManagerByte};
DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 6); DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 6);
ackPulseStart=0;
} }
break; break;
@ -354,6 +357,7 @@ void DCC::ackManagerLoop() {
// DIAG(F("\nVB %d %d"),ackManagerCv,ackManagerByte); // DIAG(F("\nVB %d %d"),ackManagerCv,ackManagerByte);
byte message[] = { cv1(VERIFY_BYTE, ackManagerCv), cv2(ackManagerCv), ackManagerByte}; byte message[] = { cv1(VERIFY_BYTE, ackManagerCv), cv2(ackManagerCv), ackManagerByte};
DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 5); DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 5);
ackPulseStart=0;
} }
break; break;
@ -365,6 +369,7 @@ void DCC::ackManagerLoop() {
byte instruction = VERIFY_BIT | (opcode==V0?BIT_OFF:BIT_ON) | ackManagerBitNum; byte instruction = VERIFY_BIT | (opcode==V0?BIT_OFF:BIT_ON) | ackManagerBitNum;
byte message[] = {cv1(BIT_MANIPULATE, ackManagerCv), cv2(ackManagerCv), instruction }; byte message[] = {cv1(BIT_MANIPULATE, ackManagerCv), cv2(ackManagerCv), instruction };
DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 5); DCCWaveform::progTrack.schedulePacket(message, sizeof(message), 5);
ackPulseStart=0;
} }
break; break;
@ -377,15 +382,26 @@ void DCC::ackManagerLoop() {
} }
current=Hardware::getCurrentMilliamps(false); current=Hardware::getCurrentMilliamps(false);
// An ACK is a pulse lasting between 4.5 and 8.5 mSecs (refer @haba)
if (current > ackTriggerMilliamps) { //ACK detected if (current>ackTriggerMilliamps) {
// DIAG(F("\nACK %dmA, after %d resets\n"), current,resets); if (ackPulseStart==0)ackPulseStart=micros(); // leading edge of pulse detected
ackReceived = true; return;
DCCWaveform::progTrack.killRemainingRepeats();
break; // move on tho next step
} }
return; // check again on next loop cycle. // not in pulse
if (ackPulseStart==0) return; // keep waiting for leading edge
{
long pulseDuration=micros()-ackPulseStart;
// TODO handle timer wrapover
if (pulseDuration>4500 && pulseDuration<8500) {
ackReceived=true;
DCCWaveform::progTrack.killRemainingRepeats(); // probabaly no need after 8.5ms!!
break; // we have a genuine ACK result
}
}
ackPulseStart=0; // We have detected a too-short or too-long pulse so ignore and wait for next leading edge
return; // keep waiting
case ITC0: case ITC0:
case ITC1: // If True Callback(0 or 1) (if prevous WACK got an ACK) case ITC1: // If True Callback(0 or 1) (if prevous WACK got an ACK)

1
DCC.h
View File

@ -72,6 +72,7 @@ private:
static byte ackManagerStash; static byte ackManagerStash;
static bool ackReceived; static bool ackReceived;
static int ackTriggerMilliamps; static int ackTriggerMilliamps;
static long ackPulseStart;
static ACK_CALLBACK ackManagerCallback; static ACK_CALLBACK ackManagerCallback;
static void ackManagerSetup(int cv, byte bitNumOrbyteValue, ackOp const program[], ACK_CALLBACK callback); static void ackManagerSetup(int cv, byte bitNumOrbyteValue, ackOp const program[], ACK_CALLBACK callback);
static void ackManagerLoop(); static void ackManagerLoop();