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(
"");
209 loadPacket(nReg, b, nB, 4, 1);
212 #ifdef USE_TEXTCOMMAND 213 void RegisterList::setFunction(
char *s)
volatile 219 nParams = sscanf(s,
"%d %d %d", &cab, &fByte, &eByte);
222 #ifdef DCCPP_DEBUG_MODE 223 Serial.println(F(
"f Syntax error"));
231 this->setFunction(0, cab, fByte, eByte);
238 void RegisterList::setAccessory(
int aAdd,
int aNum,
int activate)
volatile 242 b[0] = aAdd % 64 + 128;
243 b[1] = ((((aAdd / 64) % 8) << 4) + (aNum % 4 << 1) + activate % 2) ^ 0xF8;
245 loadPacket(0, b, 2, 4, 1);
249 #ifdef USE_TEXTCOMMAND 250 void RegisterList::setAccessory(
char *s)
volatile 256 if (sscanf(s,
"%d %d %d", &aAdd, &aNum, &activate) != 3)
258 #ifdef DCCPP_DEBUG_MODE 259 Serial.println(F(
"a Syntax error"));
264 this->setAccessory(aAdd, aNum, activate);
271 void RegisterList::writeTextPacket(
int nReg, byte *b,
int nBytes)
volatile 274 if (nBytes<2 || nBytes>5) {
275 INTERFACE.print(
"<mInvalid Packet>");
276 #if !defined(USE_ETHERNET) 277 INTERFACE.println(
"");
282 loadPacket(nReg, b, nBytes, 0, 1);
286 #ifdef USE_TEXTCOMMAND 287 void RegisterList::writeTextPacket(
char *s)
volatile 293 nBytes = sscanf(s,
"%d %hhx %hhx %hhx %hhx %hhx", &nReg, b, b + 1, b + 2, b + 3, b + 4) - 1;
295 this->writeTextPacket(nReg, b, nBytes);
302 int RegisterList::readCVraw(
int cv,
int callBack,
int callBackSub,
bool FromProg)
volatile 309 byte MonitorPin = DCCppConfig::CurrentMonitorProg;
311 MonitorPin = DCCppConfig::CurrentMonitorMain;
313 if (MonitorPin == UNDEFINED_PIN)
316 bRead[0] = 0x78 + (highByte(cv) & 0x03);
317 bRead[1] = lowByte(cv);
321 for (
int i = 0; i<8; i++) {
327 for (
int j = 0; j < ACK_BASE_COUNT; j++)
329 int val = (int)analogRead(MonitorPin);
332 base /= ACK_BASE_COUNT;
336 loadPacket(0, resetPacket, 2, 3);
337 loadPacket(0, bRead, 3, 5);
338 loadPacket(0, resetPacket, 2, 1);
340 for (
int j = 0; j<ACK_SAMPLE_COUNT; j++)
342 int val = (int)analogRead(MonitorPin);
343 c = (int)((val - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
344 if (c>ACK_SAMPLE_THRESHOLD)
348 bitWrite(bValue, i, d);
355 for (
int j = 0; j<ACK_BASE_COUNT; j++)
356 base += analogRead(MonitorPin);
357 base /= ACK_BASE_COUNT;
359 bRead[0] = 0x74 + (highByte(cv) & 0x03);
362 loadPacket(0, resetPacket, 2, 3);
363 loadPacket(0, bRead, 3, 5);
364 loadPacket(0, resetPacket, 2, 1);
366 for (
int j = 0; j<ACK_SAMPLE_COUNT; j++) {
367 c = (int)((analogRead(MonitorPin) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
368 if (c>ACK_SAMPLE_THRESHOLD)
375 #if defined(USE_TEXTCOMMAND) 376 INTERFACE.print(
"<r");
377 INTERFACE.print(callBack);
378 INTERFACE.print(
"|");
379 INTERFACE.print(callBackSub);
380 INTERFACE.print(
"|");
381 INTERFACE.print(cv + 1);
382 INTERFACE.print(
" ");
383 INTERFACE.print(bValue);
384 INTERFACE.print(
">");
385 #if !defined(USE_ETHERNET) 386 INTERFACE.println(
"");
393 void RegisterList::readCV(
int cv,
int callBack,
int callBackSub)
volatile 395 RegisterList::readCVraw(cv, callBack, callBackSub,
true);
399 #ifdef USE_TEXTCOMMAND 400 void RegisterList::readCV(
char *s)
volatile 402 int cv, callBack, callBackSub;
404 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
406 #ifdef DCCPP_DEBUG_MODE 407 Serial.println(F(
"R Syntax error"));
412 this->readCV(cv, callBack, callBackSub);
416 int RegisterList::readCVmain(
int cv,
int callBack,
int callBackSub)
volatile 418 return RegisterList::readCVraw(cv, callBack, callBackSub,
false);
422 #ifdef USE_TEXTCOMMAND 423 int RegisterList::readCVmain(
char *s)
volatile 425 int cv, callBack, callBackSub;
427 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
429 #ifdef DCCPP_DEBUG_MODE 430 Serial.println(F(
"r Syntax error"));
435 return this->readCVmain(cv, callBack, callBackSub);
441 void RegisterList::writeCVByte(
int cv,
int bValue,
int callBack,
int callBackSub)
volatile 448 bWrite[0] = 0x7C + (highByte(cv) & 0x03);
449 bWrite[1] = lowByte(cv);
452 loadPacket(0, resetPacket, 2, 1);
453 loadPacket(0, bWrite, 3, 4);
454 loadPacket(0, resetPacket, 2, 1);
455 loadPacket(0, idlePacket, 2, 10);
458 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
464 for (
int j = 0; j < ACK_BASE_COUNT; j++)
465 base += analogRead(DCCppConfig::CurrentMonitorProg);
466 base /= ACK_BASE_COUNT;
468 bWrite[0] = 0x74 + (highByte(cv) & 0x03);
470 loadPacket(0, resetPacket, 2, 3);
471 loadPacket(0, bWrite, 3, 5);
472 loadPacket(0, resetPacket, 2, 1);
474 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
475 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
476 if (c > ACK_SAMPLE_THRESHOLD)
484 #if defined(USE_TEXTCOMMAND) 485 INTERFACE.print(
"<r");
486 INTERFACE.print(callBack);
487 INTERFACE.print(
"|");
488 INTERFACE.print(callBackSub);
489 INTERFACE.print(
"|");
490 INTERFACE.print(cv + 1);
491 INTERFACE.print(
" ");
492 INTERFACE.print(bValue);
493 INTERFACE.print(
">");
494 #if !defined(USE_ETHERNET) 495 INTERFACE.println(
"");
500 #ifdef USE_TEXTCOMMAND 501 void RegisterList::writeCVByte(
char *s)
volatile 503 int bValue, cv, callBack, callBackSub;
505 if (sscanf(s,
"%d %d %d %d", &cv, &bValue, &callBack, &callBackSub) != 4)
507 #ifdef DCCPP_DEBUG_MODE 508 Serial.println(F(
"W Syntax error"));
513 this->writeCVByte(cv, bValue, callBack, callBackSub);
519 void RegisterList::writeCVBit(
int cv,
int bNum,
int bValue,
int callBack,
int callBackSub)
volatile 528 bWrite[0] = 0x78 + (highByte(cv) & 0x03);
529 bWrite[1] = lowByte(cv);
530 bWrite[2] = 0xF0 + bValue * 8 + bNum;
532 loadPacket(0, resetPacket, 2, 1);
533 loadPacket(0, bWrite, 3, 4);
534 loadPacket(0, resetPacket, 2, 1);
535 loadPacket(0, idlePacket, 2, 10);
538 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
544 for (
int j = 0; j < ACK_BASE_COUNT; j++)
545 base += analogRead(DCCppConfig::CurrentMonitorProg);
546 base /= ACK_BASE_COUNT;
548 bitClear(bWrite[2], 4);
550 loadPacket(0, resetPacket, 2, 3);
551 loadPacket(0, bWrite, 3, 5);
552 loadPacket(0, resetPacket, 2, 1);
554 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
555 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
556 if (c > ACK_SAMPLE_THRESHOLD)
564 #if defined(USE_TEXTCOMMAND) 565 INTERFACE.print(
"<r");
566 INTERFACE.print(callBack);
567 INTERFACE.print(
"|");
568 INTERFACE.print(callBackSub);
569 INTERFACE.print(
"|");
570 INTERFACE.print(cv + 1);
571 INTERFACE.print(
" ");
572 INTERFACE.print(bNum);
573 INTERFACE.print(
" ");
574 INTERFACE.print(bValue);
575 INTERFACE.print(
">");
576 #if !defined(USE_ETHERNET) 577 INTERFACE.println(
"");
582 #ifdef USE_TEXTCOMMAND 583 void RegisterList::writeCVBit(
char *s)
volatile 585 int bNum, bValue, cv, callBack, callBackSub;
587 if(sscanf(s,
"%d %d %d %d %d",&cv,&bNum,&bValue,&callBack,&callBackSub) != 5)
589 #ifdef DCCPP_DEBUG_MODE 590 Serial.println(F(
"W Syntax error"));
595 this->writeCVBit(cv, bNum, bValue, callBack, callBackSub);
601 void RegisterList::writeCVByteMain(
int cab,
int cv,
int bValue)
volatile 609 b[nB++] = highByte(cab) | 0xC0;
611 b[nB++] = lowByte(cab);
612 b[nB++] = 0xEC + (highByte(cv) & 0x03);
613 b[nB++] = lowByte(cv);
616 loadPacket(0, b, nB, 4);
620 #ifdef USE_TEXTCOMMAND 621 void RegisterList::writeCVByteMain(
char *s)
volatile 627 if (sscanf(s,
"%d %d %d", &cab, &cv, &bValue) != 3)
629 #ifdef DCCPP_DEBUG_MODE 630 Serial.println(F(
"w Syntax error"));
635 this->writeCVByteMain(cab, cv, bValue);
641 void RegisterList::writeCVBitMain(
int cab,
int cv,
int bNum,
int bValue)
volatile 652 b[nB++] = highByte(cab) | 0xC0;
654 b[nB++] = lowByte(cab);
655 b[nB++] = 0xE8 + (highByte(cv) & 0x03);
656 b[nB++] = lowByte(cv);
657 b[nB++] = 0xF0 + bValue * 8 + bNum;
659 loadPacket(0, b, nB, 4);
663 #ifdef USE_TEXTCOMMAND 664 void RegisterList::writeCVBitMain(
char *s)
volatile 671 if (sscanf(s,
"%d %d %d %d", &cab, &cv, &bNum, &bValue) != 4)
673 #ifdef DCCPP_DEBUG_MODE 674 Serial.println(F(
"w Syntax error"));
679 this->writeCVBitMain(cab, cv, bNum, bValue);
685 #ifdef DCCPP_DEBUG_MODE 686 void RegisterList::printPacket(
int nReg, byte *b,
int nBytes,
int nRepeat)
volatile 688 INTERFACE.print(
"<*");
689 INTERFACE.print(nReg);
690 INTERFACE.print(
":");
691 for(
int i=0;i<nBytes;i++){
692 INTERFACE.print(
" ");
693 INTERFACE.print(b[i],HEX);
695 INTERFACE.print(
" / ");
696 INTERFACE.print(nRepeat);
697 INTERFACE.print(
">");
698 #if !defined(USE_ETHERNET) 699 INTERFACE.println(
"");
706 byte RegisterList::idlePacket[3]={0xFF,0x00,0};
707 byte RegisterList::resetPacket[3]={0x00,0x00,0};
709 byte RegisterList::bitMask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};