16 uint8_t DCCppConfig::EthernetIp[4];
17 uint8_t DCCppConfig::EthernetMac[6];
18 int DCCppConfig::EthernetPort = 0;
20 EthernetProtocol DCCppConfig::Protocol = EthernetProtocol::TCP;
23 byte DCCppConfig::SignalEnablePinMain = UNDEFINED_PIN;
24 byte DCCppConfig::CurrentMonitorMain = UNDEFINED_PIN;
26 byte DCCppConfig::SignalEnablePinProg = UNDEFINED_PIN;
27 byte DCCppConfig::CurrentMonitorProg = UNDEFINED_PIN;
29 byte DCCppConfig::DirectionMotorA = UNDEFINED_PIN;
30 byte DCCppConfig::DirectionMotorB = UNDEFINED_PIN;
34 void Register::initPackets(){
41 RegisterList::RegisterList(
int maxNumRegs){
42 this->maxNumRegs=maxNumRegs;
44 for(
int i=0;i<=maxNumRegs;i++)
47 speedTable=(
int *)calloc((maxNumRegs+1),
sizeof(
int *));
62 void RegisterList::loadPacket(
int nReg, byte *b,
int nBytes,
int nRepeat,
int printFlag)
volatile 67 nReg=nReg%((maxNumRegs+1));
71 if(regMap[nReg]==NULL)
72 regMap[nReg]=maxLoadedReg+1;
79 for(
int i=1;i<nBytes;i++)
85 buf[2]=0xFC + bitRead(b[0],7);
112 this->nRepeat=nRepeat;
113 maxLoadedReg=max(maxLoadedReg,nextReg);
115 #ifdef DCCPP_DEBUG_MODE 117 printPacket(nReg,b,nBytes,nRepeat);
124 void RegisterList::setThrottle(
int nReg,
int cab,
int tSpeed,
int tDirection)
volatile 130 b[nB++] = highByte(cab) | 0xC0;
132 b[nB++] = lowByte(cab);
135 b[nB++] = tSpeed + (tSpeed>0) + tDirection * 128;
141 loadPacket(nReg, b, nB, 0, 1);
143 #if defined(USE_TEXTCOMMAND) 144 INTERFACE.print(
"<T");
145 INTERFACE.print(nReg); INTERFACE.print(
" ");
146 INTERFACE.print(cab); INTERFACE.print(
" ");
147 INTERFACE.print(tSpeed); INTERFACE.print(
" ");
148 INTERFACE.print(tDirection);
149 INTERFACE.print(
">");
150 #if !defined(USE_ETHERNET) 151 INTERFACE.println(
"");
154 speedTable[nReg] = tDirection == 1 ? tSpeed : -tSpeed;
158 #ifdef USE_TEXTCOMMAND 159 void RegisterList::setThrottle(
char *s)
volatile 166 if (sscanf(s,
"%d %d %d %d", &nReg, &cab, &tSpeed, &tDirection) != 4)
168 #ifdef DCCPP_DEBUG_MODE 169 Serial.println(F(
"t Syntax error"));
174 this->setThrottle(nReg, cab, tSpeed, tDirection);
180 void RegisterList::setFunction(
int nReg,
int cab,
int fByte,
int eByte)
volatile 186 b[nB++] = highByte(cab) | 0xC0;
188 b[nB++] = lowByte(cab);
191 b[nB++] = (fByte | 0x80) & 0xBF;
194 b[nB++] = (fByte | 0xDE) & 0xDF;
198 #if defined(USE_TEXTCOMMAND) 199 INTERFACE.print(
"<F");
200 INTERFACE.print(nReg); INTERFACE.print(
" ");
201 INTERFACE.print(cab); INTERFACE.print(
" ");
202 INTERFACE.print(fByte); INTERFACE.print(
" ");
203 INTERFACE.print(eByte);
204 INTERFACE.print(
">");
205 #if !defined(USE_ETHERNET) 206 INTERFACE.println(
"");
214 loadPacket(nReg, b, nB, 4, 1);
215 loadPacket(nReg, b, nB, 4, 1);
218 #ifdef USE_TEXTCOMMAND 219 void RegisterList::setFunction(
char *s)
volatile 225 nParams = sscanf(s,
"%d %d %d", &cab, &fByte, &eByte);
228 #ifdef DCCPP_DEBUG_MODE 229 Serial.println(F(
"f Syntax error"));
237 this->setFunction(0, cab, fByte, eByte);
244 void RegisterList::setAccessory(
int aAdd,
int aNum,
int activate)
volatile 248 b[0] = aAdd % 64 + 128;
249 b[1] = ((((aAdd / 64) % 8) << 4) + (aNum % 4 << 1) + activate % 2) ^ 0xF8;
251 loadPacket(0, b, 2, 4, 1);
255 #ifdef USE_TEXTCOMMAND 256 void RegisterList::setAccessory(
char *s)
volatile 262 if (sscanf(s,
"%d %d %d", &aAdd, &aNum, &activate) != 3)
264 #ifdef DCCPP_DEBUG_MODE 265 Serial.println(F(
"a Syntax error"));
270 this->setAccessory(aAdd, aNum, activate);
277 void RegisterList::writeTextPacket(
int nReg, byte *b,
int nBytes)
volatile 280 if (nBytes<2 || nBytes>5) {
281 INTERFACE.print(
"<mInvalid Packet>");
282 #if !defined(USE_ETHERNET) 283 INTERFACE.println(
"");
288 loadPacket(nReg, b, nBytes, 0, 1);
292 #ifdef USE_TEXTCOMMAND 293 void RegisterList::writeTextPacket(
char *s)
volatile 299 nBytes = sscanf(s,
"%d %hhx %hhx %hhx %hhx %hhx", &nReg, b, b + 1, b + 2, b + 3, b + 4) - 1;
301 this->writeTextPacket(nReg, b, nBytes);
308 int RegisterList::readCVraw(
int cv,
int callBack,
int callBackSub,
bool FromProg)
volatile 315 byte MonitorPin = DCCppConfig::CurrentMonitorProg;
317 MonitorPin = DCCppConfig::CurrentMonitorMain;
319 if (MonitorPin == UNDEFINED_PIN)
322 bRead[0] = 0x78 + (highByte(cv) & 0x03);
323 bRead[1] = lowByte(cv);
327 for (
int i = 0; i<8; i++) {
333 for (
int j = 0; j < ACK_BASE_COUNT; j++)
335 int val = (int)analogRead(MonitorPin);
338 base /= ACK_BASE_COUNT;
342 loadPacket(0, resetPacket, 2, 3);
343 loadPacket(0, bRead, 3, 5);
344 loadPacket(0, resetPacket, 2, 1);
346 for (
int j = 0; j<ACK_SAMPLE_COUNT; j++)
348 int val = (int)analogRead(MonitorPin);
349 c = (int)((val - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
350 if (c>ACK_SAMPLE_THRESHOLD)
354 bitWrite(bValue, i, d);
361 for (
int j = 0; j<ACK_BASE_COUNT; j++)
362 base += analogRead(MonitorPin);
363 base /= ACK_BASE_COUNT;
365 bRead[0] = 0x74 + (highByte(cv) & 0x03);
368 loadPacket(0, resetPacket, 2, 3);
369 loadPacket(0, bRead, 3, 5);
370 loadPacket(0, resetPacket, 2, 1);
372 for (
int j = 0; j<ACK_SAMPLE_COUNT; j++) {
373 c = (int)((analogRead(MonitorPin) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
374 if (c>ACK_SAMPLE_THRESHOLD)
381 #if defined(USE_TEXTCOMMAND) 382 INTERFACE.print(
"<r");
383 INTERFACE.print(callBack);
384 INTERFACE.print(
"|");
385 INTERFACE.print(callBackSub);
386 INTERFACE.print(
"|");
387 INTERFACE.print(cv + 1);
388 INTERFACE.print(
" ");
389 INTERFACE.print(bValue);
390 INTERFACE.print(
">");
391 #if !defined(USE_ETHERNET) 392 INTERFACE.println(
"");
399 void RegisterList::readCV(
int cv,
int callBack,
int callBackSub)
volatile 401 RegisterList::readCVraw(cv, callBack, callBackSub,
true);
405 #ifdef USE_TEXTCOMMAND 406 void RegisterList::readCV(
char *s)
volatile 408 int cv, callBack, callBackSub;
410 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
412 #ifdef DCCPP_DEBUG_MODE 413 Serial.println(F(
"R Syntax error"));
418 this->readCV(cv, callBack, callBackSub);
422 int RegisterList::readCVmain(
int cv,
int callBack,
int callBackSub)
volatile 424 return RegisterList::readCVraw(cv, callBack, callBackSub,
false);
428 #ifdef USE_TEXTCOMMAND 429 int RegisterList::readCVmain(
char *s)
volatile 431 int cv, callBack, callBackSub;
433 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
435 #ifdef DCCPP_DEBUG_MODE 436 Serial.println(F(
"r Syntax error"));
441 return this->readCVmain(cv, callBack, callBackSub);
447 void RegisterList::writeCVByte(
int cv,
int bValue,
int callBack,
int callBackSub)
volatile 454 bWrite[0] = 0x7C + (highByte(cv) & 0x03);
455 bWrite[1] = lowByte(cv);
458 loadPacket(0, resetPacket, 2, 1);
459 loadPacket(0, bWrite, 3, 4);
460 loadPacket(0, resetPacket, 2, 1);
461 loadPacket(0, idlePacket, 2, 10);
464 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
470 for (
int j = 0; j < ACK_BASE_COUNT; j++)
471 base += analogRead(DCCppConfig::CurrentMonitorProg);
472 base /= ACK_BASE_COUNT;
474 bWrite[0] = 0x74 + (highByte(cv) & 0x03);
476 loadPacket(0, resetPacket, 2, 3);
477 loadPacket(0, bWrite, 3, 5);
478 loadPacket(0, resetPacket, 2, 1);
480 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
481 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
482 if (c > ACK_SAMPLE_THRESHOLD)
490 #if defined(USE_TEXTCOMMAND) 491 INTERFACE.print(
"<r");
492 INTERFACE.print(callBack);
493 INTERFACE.print(
"|");
494 INTERFACE.print(callBackSub);
495 INTERFACE.print(
"|");
496 INTERFACE.print(cv + 1);
497 INTERFACE.print(
" ");
498 INTERFACE.print(bValue);
499 INTERFACE.print(
">");
500 #if !defined(USE_ETHERNET) 501 INTERFACE.println(
"");
506 #ifdef USE_TEXTCOMMAND 507 void RegisterList::writeCVByte(
char *s)
volatile 509 int bValue, cv, callBack, callBackSub;
511 if (sscanf(s,
"%d %d %d %d", &cv, &bValue, &callBack, &callBackSub) != 4)
513 #ifdef DCCPP_DEBUG_MODE 514 Serial.println(F(
"W Syntax error"));
519 this->writeCVByte(cv, bValue, callBack, callBackSub);
525 void RegisterList::writeCVBit(
int cv,
int bNum,
int bValue,
int callBack,
int callBackSub)
volatile 534 bWrite[0] = 0x78 + (highByte(cv) & 0x03);
535 bWrite[1] = lowByte(cv);
536 bWrite[2] = 0xF0 + bValue * 8 + bNum;
538 loadPacket(0, resetPacket, 2, 1);
539 loadPacket(0, bWrite, 3, 4);
540 loadPacket(0, resetPacket, 2, 1);
541 loadPacket(0, idlePacket, 2, 10);
544 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
550 for (
int j = 0; j < ACK_BASE_COUNT; j++)
551 base += analogRead(DCCppConfig::CurrentMonitorProg);
552 base /= ACK_BASE_COUNT;
554 bitClear(bWrite[2], 4);
556 loadPacket(0, resetPacket, 2, 3);
557 loadPacket(0, bWrite, 3, 5);
558 loadPacket(0, resetPacket, 2, 1);
560 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
561 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
562 if (c > ACK_SAMPLE_THRESHOLD)
570 #if defined(USE_TEXTCOMMAND) 571 INTERFACE.print(
"<r");
572 INTERFACE.print(callBack);
573 INTERFACE.print(
"|");
574 INTERFACE.print(callBackSub);
575 INTERFACE.print(
"|");
576 INTERFACE.print(cv + 1);
577 INTERFACE.print(
" ");
578 INTERFACE.print(bNum);
579 INTERFACE.print(
" ");
580 INTERFACE.print(bValue);
581 INTERFACE.print(
">");
582 #if !defined(USE_ETHERNET) 583 INTERFACE.println(
"");
588 #ifdef USE_TEXTCOMMAND 589 void RegisterList::writeCVBit(
char *s)
volatile 591 int bNum, bValue, cv, callBack, callBackSub;
593 if(sscanf(s,
"%d %d %d %d %d",&cv,&bNum,&bValue,&callBack,&callBackSub) != 5)
595 #ifdef DCCPP_DEBUG_MODE 596 Serial.println(F(
"W Syntax error"));
601 this->writeCVBit(cv, bNum, bValue, callBack, callBackSub);
607 void RegisterList::writeCVByteMain(
int cab,
int cv,
int bValue)
volatile 615 b[nB++] = highByte(cab) | 0xC0;
617 b[nB++] = lowByte(cab);
618 b[nB++] = 0xEC + (highByte(cv) & 0x03);
619 b[nB++] = lowByte(cv);
622 loadPacket(0, b, nB, 4);
626 #ifdef USE_TEXTCOMMAND 627 void RegisterList::writeCVByteMain(
char *s)
volatile 633 if (sscanf(s,
"%d %d %d", &cab, &cv, &bValue) != 3)
635 #ifdef DCCPP_DEBUG_MODE 636 Serial.println(F(
"w Syntax error"));
641 this->writeCVByteMain(cab, cv, bValue);
647 void RegisterList::writeCVBitMain(
int cab,
int cv,
int bNum,
int bValue)
volatile 658 b[nB++] = highByte(cab) | 0xC0;
660 b[nB++] = lowByte(cab);
661 b[nB++] = 0xE8 + (highByte(cv) & 0x03);
662 b[nB++] = lowByte(cv);
663 b[nB++] = 0xF0 + bValue * 8 + bNum;
665 loadPacket(0, b, nB, 4);
669 #ifdef USE_TEXTCOMMAND 670 void RegisterList::writeCVBitMain(
char *s)
volatile 677 if (sscanf(s,
"%d %d %d %d", &cab, &cv, &bNum, &bValue) != 4)
679 #ifdef DCCPP_DEBUG_MODE 680 Serial.println(F(
"w Syntax error"));
685 this->writeCVBitMain(cab, cv, bNum, bValue);
691 #ifdef DCCPP_DEBUG_MODE 692 void RegisterList::printPacket(
int nReg, byte *b,
int nBytes,
int nRepeat)
volatile 694 INTERFACE.print(
"<*");
695 INTERFACE.print(nReg);
696 INTERFACE.print(
":");
697 for(
int i=0;i<nBytes;i++){
698 INTERFACE.print(
" ");
699 INTERFACE.print(b[i],HEX);
701 INTERFACE.print(
" / ");
702 INTERFACE.print(nRepeat);
703 INTERFACE.print(
">");
704 #if !defined(USE_ETHERNET) 705 INTERFACE.println(
"");
712 byte RegisterList::idlePacket[3]={0xFF,0x00,0};
713 byte RegisterList::resetPacket[3]={0x00,0x00,0};
715 byte RegisterList::bitMask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};