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);
217 #ifdef USE_TEXTCOMMAND 218 void RegisterList::setFunction(
char *s)
volatile 224 nParams = sscanf(s,
"%d %d %d", &cab, &fByte, &eByte);
227 #ifdef DCCPP_DEBUG_MODE 228 Serial.println(F(
"f Syntax error"));
236 this->setFunction(0, cab, fByte, eByte);
243 void RegisterList::setAccessory(
int aAdd,
int aNum,
int activate)
volatile 247 b[0] = aAdd % 64 + 128;
248 b[1] = ((((aAdd / 64) % 8) << 4) + (aNum % 4 << 1) + activate % 2) ^ 0xF8;
250 loadPacket(0, b, 2, 4, 1);
254 #ifdef USE_TEXTCOMMAND 255 void RegisterList::setAccessory(
char *s)
volatile 261 if (sscanf(s,
"%d %d %d", &aAdd, &aNum, &activate) != 3)
263 #ifdef DCCPP_DEBUG_MODE 264 Serial.println(F(
"a Syntax error"));
269 this->setAccessory(aAdd, aNum, activate);
276 void RegisterList::writeTextPacket(
int nReg, byte *b,
int nBytes)
volatile 279 if (nBytes<2 || nBytes>5) {
280 INTERFACE.print(
"<mInvalid Packet>");
281 #if !defined(USE_ETHERNET) 282 INTERFACE.println(
"");
287 loadPacket(nReg, b, nBytes, 0, 1);
291 #ifdef USE_TEXTCOMMAND 292 void RegisterList::writeTextPacket(
char *s)
volatile 298 nBytes = sscanf(s,
"%d %hhx %hhx %hhx %hhx %hhx", &nReg, b, b + 1, b + 2, b + 3, b + 4) - 1;
300 this->writeTextPacket(nReg, b, nBytes);
307 int RegisterList::readCVraw(
int cv,
int callBack,
int callBackSub)
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 return RegisterList::readCVraw(cv, callBack, callBackSub);
404 #ifdef USE_TEXTCOMMAND 405 int RegisterList::readCV(
char *s)
volatile 407 int cv, callBack, callBackSub;
409 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
411 #ifdef DCCPP_DEBUG_MODE 412 Serial.println(F(
"R Syntax error"));
417 return this->readCV(cv, callBack, callBackSub);
421 int RegisterList::readCVmain(
int cv,
int callBack,
int callBackSub)
volatile 423 return RegisterList::readCVraw(cv, callBack, callBackSub);
427 #ifdef USE_TEXTCOMMAND 428 int RegisterList::readCVmain(
char *s)
volatile 430 int cv, callBack, callBackSub;
432 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
434 #ifdef DCCPP_DEBUG_MODE 435 Serial.println(F(
"r Syntax error"));
440 return this->readCVmain(cv, callBack, callBackSub);
446 void RegisterList::writeCVByte(
int cv,
int bValue,
int callBack,
int callBackSub)
volatile 453 bWrite[0] = 0x7C + (highByte(cv) & 0x03);
454 bWrite[1] = lowByte(cv);
457 loadPacket(0, resetPacket, 2, 1);
458 loadPacket(0, bWrite, 3, 4);
459 loadPacket(0, resetPacket, 2, 1);
460 loadPacket(0, idlePacket, 2, 10);
463 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
469 for (
int j = 0; j < ACK_BASE_COUNT; j++)
470 base += analogRead(DCCppConfig::CurrentMonitorProg);
471 base /= ACK_BASE_COUNT;
473 bWrite[0] = 0x74 + (highByte(cv) & 0x03);
475 loadPacket(0, resetPacket, 2, 3);
476 loadPacket(0, bWrite, 3, 5);
477 loadPacket(0, resetPacket, 2, 1);
479 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
480 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
481 if (c > ACK_SAMPLE_THRESHOLD)
489 #if defined(USE_TEXTCOMMAND) 490 INTERFACE.print(
"<r");
491 INTERFACE.print(callBack);
492 INTERFACE.print(
"|");
493 INTERFACE.print(callBackSub);
494 INTERFACE.print(
"|");
495 INTERFACE.print(cv + 1);
496 INTERFACE.print(
" ");
497 INTERFACE.print(bValue);
498 INTERFACE.print(
">");
499 #if !defined(USE_ETHERNET) 500 INTERFACE.println(
"");
505 #ifdef USE_TEXTCOMMAND 506 void RegisterList::writeCVByte(
char *s)
volatile 508 int bValue, cv, callBack, callBackSub;
510 if (sscanf(s,
"%d %d %d %d", &cv, &bValue, &callBack, &callBackSub) != 4)
512 #ifdef DCCPP_DEBUG_MODE 513 Serial.println(F(
"W Syntax error"));
518 this->writeCVByte(cv, bValue, callBack, callBackSub);
524 void RegisterList::writeCVBit(
int cv,
int bNum,
int bValue,
int callBack,
int callBackSub)
volatile 533 bWrite[0] = 0x78 + (highByte(cv) & 0x03);
534 bWrite[1] = lowByte(cv);
535 bWrite[2] = 0xF0 + bValue * 8 + bNum;
537 loadPacket(0, resetPacket, 2, 1);
538 loadPacket(0, bWrite, 3, 4);
539 loadPacket(0, resetPacket, 2, 1);
540 loadPacket(0, idlePacket, 2, 10);
543 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
549 for (
int j = 0; j < ACK_BASE_COUNT; j++)
550 base += analogRead(DCCppConfig::CurrentMonitorProg);
551 base /= ACK_BASE_COUNT;
553 bitClear(bWrite[2], 4);
555 loadPacket(0, resetPacket, 2, 3);
556 loadPacket(0, bWrite, 3, 5);
557 loadPacket(0, resetPacket, 2, 1);
559 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
560 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
561 if (c > ACK_SAMPLE_THRESHOLD)
569 #if defined(USE_TEXTCOMMAND) 570 INTERFACE.print(
"<r");
571 INTERFACE.print(callBack);
572 INTERFACE.print(
"|");
573 INTERFACE.print(callBackSub);
574 INTERFACE.print(
"|");
575 INTERFACE.print(cv + 1);
576 INTERFACE.print(
" ");
577 INTERFACE.print(bNum);
578 INTERFACE.print(
" ");
579 INTERFACE.print(bValue);
580 INTERFACE.print(
">");
581 #if !defined(USE_ETHERNET) 582 INTERFACE.println(
"");
587 #ifdef USE_TEXTCOMMAND 588 void RegisterList::writeCVBit(
char *s)
volatile 590 int bNum, bValue, cv, callBack, callBackSub;
592 if(sscanf(s,
"%d %d %d %d %d",&cv,&bNum,&bValue,&callBack,&callBackSub) != 5)
594 #ifdef DCCPP_DEBUG_MODE 595 Serial.println(F(
"W Syntax error"));
600 this->writeCVBit(cv, bNum, bValue, callBack, callBackSub);
606 void RegisterList::writeCVByteMain(
int cab,
int cv,
int bValue)
volatile 614 b[nB++] = highByte(cab) | 0xC0;
616 b[nB++] = lowByte(cab);
617 b[nB++] = 0xEC + (highByte(cv) & 0x03);
618 b[nB++] = lowByte(cv);
621 loadPacket(0, b, nB, 4);
625 #ifdef USE_TEXTCOMMAND 626 void RegisterList::writeCVByteMain(
char *s)
volatile 632 if (sscanf(s,
"%d %d %d", &cab, &cv, &bValue) != 3)
634 #ifdef DCCPP_DEBUG_MODE 635 Serial.println(F(
"w Syntax error"));
640 this->writeCVByteMain(cab, cv, bValue);
646 void RegisterList::writeCVBitMain(
int cab,
int cv,
int bNum,
int bValue)
volatile 657 b[nB++] = highByte(cab) | 0xC0;
659 b[nB++] = lowByte(cab);
660 b[nB++] = 0xE8 + (highByte(cv) & 0x03);
661 b[nB++] = lowByte(cv);
662 b[nB++] = 0xF0 + bValue * 8 + bNum;
664 loadPacket(0, b, nB, 4);
668 #ifdef USE_TEXTCOMMAND 669 void RegisterList::writeCVBitMain(
char *s)
volatile 676 if (sscanf(s,
"%d %d %d %d", &cab, &cv, &bNum, &bValue) != 4)
678 #ifdef DCCPP_DEBUG_MODE 679 Serial.println(F(
"w Syntax error"));
684 this->writeCVBitMain(cab, cv, bNum, bValue);
690 #ifdef DCCPP_DEBUG_MODE 691 void RegisterList::printPacket(
int nReg, byte *b,
int nBytes,
int nRepeat)
volatile 693 INTERFACE.print(
"<*");
694 INTERFACE.print(nReg);
695 INTERFACE.print(
":");
696 for(
int i=0;i<nBytes;i++){
697 INTERFACE.print(
" ");
698 INTERFACE.print(b[i],HEX);
700 INTERFACE.print(
" / ");
701 INTERFACE.print(nRepeat);
702 INTERFACE.print(
">");
703 #if !defined(USE_ETHERNET) 704 INTERFACE.println(
"");
711 byte RegisterList::idlePacket[3]={0xFF,0x00,0};
712 byte RegisterList::resetPacket[3]={0x00,0x00,0};
714 byte RegisterList::bitMask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
static bool IsMainTrack(volatile RegisterList *apRegs)