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 int RegisterList::readCV(
int cv,
int callBack,
int callBackSub)
volatile 401 int bValue = RegisterList::readCVraw(cv, callBack, callBackSub,
true);
406 #ifdef USE_TEXTCOMMAND 407 int RegisterList::readCV(
char *s)
volatile 409 int cv, callBack, callBackSub;
411 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
413 #ifdef DCCPP_DEBUG_MODE 414 Serial.println(F(
"R Syntax error"));
419 return this->readCV(cv, callBack, callBackSub);
423 int RegisterList::readCVmain(
int cv,
int callBack,
int callBackSub)
volatile 425 return RegisterList::readCVraw(cv, callBack, callBackSub,
false);
429 #ifdef USE_TEXTCOMMAND 430 int RegisterList::readCVmain(
char *s)
volatile 432 int cv, callBack, callBackSub;
434 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
436 #ifdef DCCPP_DEBUG_MODE 437 Serial.println(F(
"r Syntax error"));
442 return this->readCVmain(cv, callBack, callBackSub);
448 void RegisterList::writeCVByte(
int cv,
int bValue,
int callBack,
int callBackSub)
volatile 455 bWrite[0] = 0x7C + (highByte(cv) & 0x03);
456 bWrite[1] = lowByte(cv);
459 loadPacket(0, resetPacket, 2, 1);
460 loadPacket(0, bWrite, 3, 4);
461 loadPacket(0, resetPacket, 2, 1);
462 loadPacket(0, idlePacket, 2, 10);
465 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
471 for (
int j = 0; j < ACK_BASE_COUNT; j++)
472 base += analogRead(DCCppConfig::CurrentMonitorProg);
473 base /= ACK_BASE_COUNT;
475 bWrite[0] = 0x74 + (highByte(cv) & 0x03);
477 loadPacket(0, resetPacket, 2, 3);
478 loadPacket(0, bWrite, 3, 5);
479 loadPacket(0, resetPacket, 2, 1);
481 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
482 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
483 if (c > ACK_SAMPLE_THRESHOLD)
491 #if defined(USE_TEXTCOMMAND) 492 INTERFACE.print(
"<r");
493 INTERFACE.print(callBack);
494 INTERFACE.print(
"|");
495 INTERFACE.print(callBackSub);
496 INTERFACE.print(
"|");
497 INTERFACE.print(cv + 1);
498 INTERFACE.print(
" ");
499 INTERFACE.print(bValue);
500 INTERFACE.print(
">");
501 #if !defined(USE_ETHERNET) 502 INTERFACE.println(
"");
507 #ifdef USE_TEXTCOMMAND 508 void RegisterList::writeCVByte(
char *s)
volatile 510 int bValue, cv, callBack, callBackSub;
512 if (sscanf(s,
"%d %d %d %d", &cv, &bValue, &callBack, &callBackSub) != 4)
514 #ifdef DCCPP_DEBUG_MODE 515 Serial.println(F(
"W Syntax error"));
520 this->writeCVByte(cv, bValue, callBack, callBackSub);
526 void RegisterList::writeCVBit(
int cv,
int bNum,
int bValue,
int callBack,
int callBackSub)
volatile 535 bWrite[0] = 0x78 + (highByte(cv) & 0x03);
536 bWrite[1] = lowByte(cv);
537 bWrite[2] = 0xF0 + bValue * 8 + bNum;
539 loadPacket(0, resetPacket, 2, 1);
540 loadPacket(0, bWrite, 3, 4);
541 loadPacket(0, resetPacket, 2, 1);
542 loadPacket(0, idlePacket, 2, 10);
545 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
551 for (
int j = 0; j < ACK_BASE_COUNT; j++)
552 base += analogRead(DCCppConfig::CurrentMonitorProg);
553 base /= ACK_BASE_COUNT;
555 bitClear(bWrite[2], 4);
557 loadPacket(0, resetPacket, 2, 3);
558 loadPacket(0, bWrite, 3, 5);
559 loadPacket(0, resetPacket, 2, 1);
561 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
562 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
563 if (c > ACK_SAMPLE_THRESHOLD)
571 #if defined(USE_TEXTCOMMAND) 572 INTERFACE.print(
"<r");
573 INTERFACE.print(callBack);
574 INTERFACE.print(
"|");
575 INTERFACE.print(callBackSub);
576 INTERFACE.print(
"|");
577 INTERFACE.print(cv + 1);
578 INTERFACE.print(
" ");
579 INTERFACE.print(bNum);
580 INTERFACE.print(
" ");
581 INTERFACE.print(bValue);
582 INTERFACE.print(
">");
583 #if !defined(USE_ETHERNET) 584 INTERFACE.println(
"");
589 #ifdef USE_TEXTCOMMAND 590 void RegisterList::writeCVBit(
char *s)
volatile 592 int bNum, bValue, cv, callBack, callBackSub;
594 if(sscanf(s,
"%d %d %d %d %d",&cv,&bNum,&bValue,&callBack,&callBackSub) != 5)
596 #ifdef DCCPP_DEBUG_MODE 597 Serial.println(F(
"W Syntax error"));
602 this->writeCVBit(cv, bNum, bValue, callBack, callBackSub);
608 void RegisterList::writeCVByteMain(
int cab,
int cv,
int bValue)
volatile 616 b[nB++] = highByte(cab) | 0xC0;
618 b[nB++] = lowByte(cab);
619 b[nB++] = 0xEC + (highByte(cv) & 0x03);
620 b[nB++] = lowByte(cv);
623 loadPacket(0, b, nB, 4);
627 #ifdef USE_TEXTCOMMAND 628 void RegisterList::writeCVByteMain(
char *s)
volatile 634 if (sscanf(s,
"%d %d %d", &cab, &cv, &bValue) != 3)
636 #ifdef DCCPP_DEBUG_MODE 637 Serial.println(F(
"w Syntax error"));
642 this->writeCVByteMain(cab, cv, bValue);
648 void RegisterList::writeCVBitMain(
int cab,
int cv,
int bNum,
int bValue)
volatile 659 b[nB++] = highByte(cab) | 0xC0;
661 b[nB++] = lowByte(cab);
662 b[nB++] = 0xE8 + (highByte(cv) & 0x03);
663 b[nB++] = lowByte(cv);
664 b[nB++] = 0xF0 + bValue * 8 + bNum;
666 loadPacket(0, b, nB, 4);
670 #ifdef USE_TEXTCOMMAND 671 void RegisterList::writeCVBitMain(
char *s)
volatile 678 if (sscanf(s,
"%d %d %d %d", &cab, &cv, &bNum, &bValue) != 4)
680 #ifdef DCCPP_DEBUG_MODE 681 Serial.println(F(
"w Syntax error"));
686 this->writeCVBitMain(cab, cv, bNum, bValue);
692 #ifdef DCCPP_DEBUG_MODE 693 void RegisterList::printPacket(
int nReg, byte *b,
int nBytes,
int nRepeat)
volatile 695 INTERFACE.print(
"<*");
696 INTERFACE.print(nReg);
697 INTERFACE.print(
":");
698 for(
int i=0;i<nBytes;i++){
699 INTERFACE.print(
" ");
700 INTERFACE.print(b[i],HEX);
702 INTERFACE.print(
" / ");
703 INTERFACE.print(nRepeat);
704 INTERFACE.print(
">");
705 #if !defined(USE_ETHERNET) 706 INTERFACE.println(
"");
713 byte RegisterList::idlePacket[3]={0xFF,0x00,0};
714 byte RegisterList::resetPacket[3]={0x00,0x00,0};
716 byte RegisterList::bitMask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};