16 uint8_t DCCppConfig::EthernetIp[4];
17 uint8_t DCCppConfig::EthernetMac[6];
18 int DCCppConfig::EthernetPort = 0;
21 byte DCCppConfig::SignalEnablePinMain = 255;
22 byte DCCppConfig::CurrentMonitorMain = 255;
24 byte DCCppConfig::SignalEnablePinProg = 255;
25 byte DCCppConfig::CurrentMonitorProg = 255;
27 byte DCCppConfig::DirectionMotorA = 255;
28 byte DCCppConfig::DirectionMotorB = 255;
32 void Register::initPackets(){
39 RegisterList::RegisterList(
int maxNumRegs){
40 this->maxNumRegs=maxNumRegs;
42 for(
int i=0;i<=maxNumRegs;i++)
45 speedTable=(
int *)calloc((maxNumRegs+1),
sizeof(
int *));
60 void RegisterList::loadPacket(
int nReg, byte *b,
int nBytes,
int nRepeat,
int printFlag)
volatile 65 nReg=nReg%((maxNumRegs+1));
69 if(regMap[nReg]==NULL)
70 regMap[nReg]=maxLoadedReg+1;
77 for(
int i=1;i<nBytes;i++)
83 buf[2]=0xFC + bitRead(b[0],7);
110 this->nRepeat=nRepeat;
111 maxLoadedReg=max(maxLoadedReg,nextReg);
113 #ifdef DCCPP_DEBUG_MODE 115 printPacket(nReg,b,nBytes,nRepeat);
122 void RegisterList::setThrottle(
int nReg,
int cab,
int tSpeed,
int tDirection)
volatile 128 b[nB++] = highByte(cab) | 0xC0;
130 b[nB++] = lowByte(cab);
133 b[nB++] = tSpeed + (tSpeed>0) + tDirection * 128;
139 loadPacket(nReg, b, nB, 0, 1);
141 #ifdef DCCPP_DEBUG_MODE 142 INTERFACE.print(
"<T");
143 INTERFACE.print(nReg); INTERFACE.print(
" ");
144 INTERFACE.print(cab); INTERFACE.print(
" ");
145 INTERFACE.print(tSpeed); INTERFACE.print(
" ");
146 INTERFACE.print(tDirection);
147 INTERFACE.println(
">");
149 speedTable[nReg] = tDirection == 1 ? tSpeed : -tSpeed;
153 void RegisterList::setThrottle(
char *s)
volatile 160 if (sscanf(s,
"%d %d %d %d", &nReg, &cab, &tSpeed, &tDirection) != 4)
162 #ifdef DCCPP_DEBUG_MODE 163 Serial.println(F(
"t Syntax error"));
168 this->setThrottle(nReg, cab, tSpeed, tDirection);
173 void RegisterList::setFunction(
int nReg,
int cab,
int fByte,
int eByte)
volatile 179 b[nB++] = highByte(cab) | 0xC0;
181 b[nB++] = lowByte(cab);
184 b[nB++] = (fByte | 0x80) & 0xBF;
187 b[nB++] = (fByte | 0xDE) & 0xDF;
191 #ifdef DCCPP_DEBUG_MODE 192 INTERFACE.print(
"<F");
193 INTERFACE.print(nReg); INTERFACE.print(
" ");
194 INTERFACE.print(cab); INTERFACE.print(
" ");
195 INTERFACE.print(fByte); INTERFACE.print(
" ");
196 INTERFACE.print(eByte);
197 INTERFACE.println(
">");
199 loadPacket(nReg, b, nB, 4, 1);
202 void RegisterList::setFunction(
char *s)
volatile 208 nParams = sscanf(s,
"%d %d %d", &cab, &fByte, &eByte);
211 #ifdef DCCPP_DEBUG_MODE 212 Serial.println(F(
"f Syntax error"));
220 this->setFunction(0, cab, fByte, eByte);
226 void RegisterList::setAccessory(
int aAdd,
int aNum,
int activate)
volatile 230 b[0] = aAdd % 64 + 128;
231 b[1] = ((((aAdd / 64) % 8) << 4) + (aNum % 4 << 1) + activate % 2) ^ 0xF8;
233 loadPacket(0, b, 2, 4, 1);
237 void RegisterList::setAccessory(
char *s)
volatile 243 if (sscanf(s,
"%d %d %d", &aAdd, &aNum, &activate) != 3)
245 #ifdef DCCPP_DEBUG_MODE 246 Serial.println(F(
"a Syntax error"));
251 this->setAccessory(aAdd, aNum, activate);
257 void RegisterList::writeTextPacket(
int nReg, byte *b,
int nBytes)
volatile 260 if (nBytes<2 || nBytes>5) {
261 INTERFACE.println(
"<mInvalid Packet>");
265 loadPacket(nReg, b, nBytes, 0, 1);
269 void RegisterList::writeTextPacket(
char *s)
volatile 275 nBytes = sscanf(s,
"%d %hhx %hhx %hhx %hhx %hhx", &nReg, b, b + 1, b + 2, b + 3, b + 4) - 1;
277 this->writeTextPacket(nReg, b, nBytes);
283 int RegisterList::readCVraw(
int cv,
int callBack,
int callBackSub,
bool FromProg)
volatile 290 byte MonitorPin = DCCppConfig::CurrentMonitorProg;
292 MonitorPin = DCCppConfig::CurrentMonitorMain;
294 if (MonitorPin == 255)
297 bRead[0] = 0x78 + (highByte(cv) & 0x03);
298 bRead[1] = lowByte(cv);
302 for (
int i = 0; i<8; i++) {
308 for (
int j = 0; j < ACK_BASE_COUNT; j++)
310 int val = (int)analogRead(MonitorPin);
313 base /= ACK_BASE_COUNT;
317 loadPacket(0, resetPacket, 2, 3);
318 loadPacket(0, bRead, 3, 5);
319 loadPacket(0, resetPacket, 2, 1);
321 for (
int j = 0; j<ACK_SAMPLE_COUNT; j++)
323 int val = (int)analogRead(MonitorPin);
324 c = (int)((val - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
325 if (c>ACK_SAMPLE_THRESHOLD)
329 bitWrite(bValue, i, d);
336 for (
int j = 0; j<ACK_BASE_COUNT; j++)
337 base += analogRead(MonitorPin);
338 base /= ACK_BASE_COUNT;
340 bRead[0] = 0x74 + (highByte(cv) & 0x03);
343 loadPacket(0, resetPacket, 2, 3);
344 loadPacket(0, bRead, 3, 5);
345 loadPacket(0, resetPacket, 2, 1);
347 for (
int j = 0; j<ACK_SAMPLE_COUNT; j++) {
348 c = (int)((analogRead(MonitorPin) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
349 if (c>ACK_SAMPLE_THRESHOLD)
356 #ifdef DCCPP_DEBUG_MODE 357 INTERFACE.print(
"<r");
358 INTERFACE.print(callBack);
359 INTERFACE.print(
"|");
360 INTERFACE.print(callBackSub);
361 INTERFACE.print(
"|");
362 INTERFACE.print(cv + 1);
363 INTERFACE.print(
" ");
364 INTERFACE.print(bValue);
365 INTERFACE.println(
">");
371 void RegisterList::readCV(
int cv,
int callBack,
int callBackSub)
volatile 373 RegisterList::readCVraw(cv, callBack, callBackSub,
true);
377 void RegisterList::readCV(
char *s)
volatile 379 int cv, callBack, callBackSub;
381 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
383 #ifdef DCCPP_DEBUG_MODE 384 Serial.println(F(
"R Syntax error"));
389 this->readCV(cv, callBack, callBackSub);
392 int RegisterList::readCVmain(
int cv,
int callBack,
int callBackSub)
volatile 394 return RegisterList::readCVraw(cv, callBack, callBackSub,
false);
398 int RegisterList::readCVmain(
char *s)
volatile 400 int cv, callBack, callBackSub;
402 if (sscanf(s,
"%d %d %d", &cv, &callBack, &callBackSub) != 3)
404 #ifdef DCCPP_DEBUG_MODE 405 Serial.println(F(
"r Syntax error"));
410 return this->readCVmain(cv, callBack, callBackSub);
415 void RegisterList::writeCVByte(
int cv,
int bValue,
int callBack,
int callBackSub)
volatile 422 bWrite[0] = 0x7C + (highByte(cv) & 0x03);
423 bWrite[1] = lowByte(cv);
426 loadPacket(0, resetPacket, 2, 1);
427 loadPacket(0, bWrite, 3, 4);
428 loadPacket(0, resetPacket, 2, 1);
429 loadPacket(0, idlePacket, 2, 10);
432 if (DCCppConfig::CurrentMonitorProg != 255)
438 for (
int j = 0; j < ACK_BASE_COUNT; j++)
439 base += analogRead(DCCppConfig::CurrentMonitorProg);
440 base /= ACK_BASE_COUNT;
442 bWrite[0] = 0x74 + (highByte(cv) & 0x03);
444 loadPacket(0, resetPacket, 2, 3);
445 loadPacket(0, bWrite, 3, 5);
446 loadPacket(0, resetPacket, 2, 1);
448 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
449 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
450 if (c > ACK_SAMPLE_THRESHOLD)
457 #ifdef DCCPP_DEBUG_MODE 458 INTERFACE.print(
"<r");
459 INTERFACE.print(callBack);
460 INTERFACE.print(
"|");
461 INTERFACE.print(callBackSub);
462 INTERFACE.print(
"|");
463 INTERFACE.print(cv + 1);
464 INTERFACE.print(
" ");
465 INTERFACE.print(bValue);
466 INTERFACE.println(
">");
471 void RegisterList::writeCVByte(
char *s)
volatile 473 int bValue, cv, callBack, callBackSub;
475 if (sscanf(s,
"%d %d %d %d", &cv, &bValue, &callBack, &callBackSub) != 4)
477 #ifdef DCCPP_DEBUG_MODE 478 Serial.println(F(
"W Syntax error"));
483 this->writeCVByte(cv, bValue, callBack, callBackSub);
488 void RegisterList::writeCVBit(
int cv,
int bNum,
int bValue,
int callBack,
int callBackSub)
volatile 497 bWrite[0] = 0x78 + (highByte(cv) & 0x03);
498 bWrite[1] = lowByte(cv);
499 bWrite[2] = 0xF0 + bValue * 8 + bNum;
501 loadPacket(0, resetPacket, 2, 1);
502 loadPacket(0, bWrite, 3, 4);
503 loadPacket(0, resetPacket, 2, 1);
504 loadPacket(0, idlePacket, 2, 10);
507 if (DCCppConfig::CurrentMonitorProg != 255)
513 for (
int j = 0; j < ACK_BASE_COUNT; j++)
514 base += analogRead(DCCppConfig::CurrentMonitorProg);
515 base /= ACK_BASE_COUNT;
517 bitClear(bWrite[2], 4);
519 loadPacket(0, resetPacket, 2, 3);
520 loadPacket(0, bWrite, 3, 5);
521 loadPacket(0, resetPacket, 2, 1);
523 for (
int j = 0; j < ACK_SAMPLE_COUNT; j++) {
524 c = (int)((analogRead(DCCppConfig::CurrentMonitorProg) - base)*ACK_SAMPLE_SMOOTHING + c*(1.0 - ACK_SAMPLE_SMOOTHING));
525 if (c > ACK_SAMPLE_THRESHOLD)
532 #ifdef DCCPP_DEBUG_MODE 533 INTERFACE.print(
"<r");
534 INTERFACE.print(callBack);
535 INTERFACE.print(
"|");
536 INTERFACE.print(callBackSub);
537 INTERFACE.print(
"|");
538 INTERFACE.print(cv + 1);
539 INTERFACE.print(
" ");
540 INTERFACE.print(bNum);
541 INTERFACE.print(
" ");
542 INTERFACE.print(bValue);
543 INTERFACE.println(
">");
548 void RegisterList::writeCVBit(
char *s)
volatile 550 int bNum, bValue, cv, callBack, callBackSub;
552 if(sscanf(s,
"%d %d %d %d %d",&cv,&bNum,&bValue,&callBack,&callBackSub) != 5)
554 #ifdef DCCPP_DEBUG_MODE 555 Serial.println(F(
"W Syntax error"));
560 this->writeCVBit(cv, bNum, bValue, callBack, callBackSub);
565 void RegisterList::writeCVByteMain(
int cab,
int cv,
int bValue)
volatile 573 b[nB++] = highByte(cab) | 0xC0;
575 b[nB++] = lowByte(cab);
576 b[nB++] = 0xEC + (highByte(cv) & 0x03);
577 b[nB++] = lowByte(cv);
580 loadPacket(0, b, nB, 4);
584 void RegisterList::writeCVByteMain(
char *s)
volatile 590 if (sscanf(s,
"%d %d %d", &cab, &cv, &bValue) != 3)
592 #ifdef DCCPP_DEBUG_MODE 593 Serial.println(F(
"w Syntax error"));
598 this->writeCVByteMain(cab, cv, bValue);
603 void RegisterList::writeCVBitMain(
int cab,
int cv,
int bNum,
int bValue)
volatile 614 b[nB++] = highByte(cab) | 0xC0;
616 b[nB++] = lowByte(cab);
617 b[nB++] = 0xE8 + (highByte(cv) & 0x03);
618 b[nB++] = lowByte(cv);
619 b[nB++] = 0xF0 + bValue * 8 + bNum;
621 loadPacket(0, b, nB, 4);
625 void RegisterList::writeCVBitMain(
char *s)
volatile 632 if (sscanf(s,
"%d %d %d %d", &cab, &cv, &bNum, &bValue) != 4)
634 #ifdef DCCPP_DEBUG_MODE 635 Serial.println(F(
"w Syntax error"));
640 this->writeCVBitMain(cab, cv, bNum, bValue);
645 #ifdef DCCPP_DEBUG_MODE 646 void RegisterList::printPacket(
int nReg, byte *b,
int nBytes,
int nRepeat)
volatile 649 INTERFACE.print(
"<*");
650 INTERFACE.print(nReg);
651 INTERFACE.print(
":");
652 for(
int i=0;i<nBytes;i++){
653 INTERFACE.print(
" ");
654 INTERFACE.print(b[i],HEX);
656 INTERFACE.print(
" / ");
657 INTERFACE.print(nRepeat);
658 INTERFACE.println(
">");
664 byte RegisterList::idlePacket[3]={0xFF,0x00,0};
665 byte RegisterList::resetPacket[3]={0x00,0x00,0};
667 byte RegisterList::bitMask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};