mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-24 16:46:13 +01:00
Compare commits
2 Commits
bd02d1c15b
...
dba5d35aa2
Author | SHA1 | Date | |
---|---|---|---|
|
dba5d35aa2 | ||
|
be10be5a1a |
|
@ -732,11 +732,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
for (uint8_t p = 0; p < posCount; p++) {
|
for (uint8_t p = 0; p < posCount; p++) {
|
||||||
StringFormatter::send(stream, F("<jP"));
|
StringFormatter::send(stream, F("<jP"));
|
||||||
int16_t value = tto->getPositionValue(p);
|
int16_t value = tto->getPositionValue(p);
|
||||||
|
int16_t angle = tto->getPositionAngle(p);
|
||||||
#ifdef EXRAIL_ACTIVE
|
#ifdef EXRAIL_ACTIVE
|
||||||
tpdesc = RMFT2::getTurntablePositionDescription(id, p);
|
tpdesc = RMFT2::getTurntablePositionDescription(id, p);
|
||||||
#endif
|
#endif
|
||||||
if (tpdesc == NULL) tpdesc = F("");
|
if (tpdesc == NULL) tpdesc = F("");
|
||||||
StringFormatter::send(stream, F(" %d %d %d \"%S\""), id, p, value, tpdesc);
|
StringFormatter::send(stream, F(" %d %d %d %d \"%S\""), id, p, value, angle, tpdesc);
|
||||||
StringFormatter::send(stream, F(">\n"));
|
StringFormatter::send(stream, F(">\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1107,44 +1108,56 @@ bool DCCEXParser::parseI(Print *stream, int16_t params, int16_t p[])
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 2: // <I id DCC> | <I id position> - rotate or create DCC turntable
|
case 2: // <I id position> - rotate a DCC turntable
|
||||||
{
|
{
|
||||||
Turntable *tto = Turntable::get(p[0]);
|
Turntable *tto = Turntable::get(p[0]);
|
||||||
if (p[1] == HASH_KEYWORD_DCC) { // Create a DCC turntable
|
if (tto && !tto->isEXTT()) {
|
||||||
if (tto) return false;
|
if (!tto->setPosition(p[0], p[1])) return false;
|
||||||
if (!DCCTurntable::create(p[0])) return false;
|
} else {
|
||||||
Turntable *tto = Turntable::get(p[0]);
|
return false;
|
||||||
tto->addPosition(0, 0);
|
|
||||||
} else { // Otherwise move a DCC turntable
|
|
||||||
if (tto && !tto->isEXTT()) {
|
|
||||||
if (!tto->setPosition(p[0], p[1])) return false;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 3: // <I id position activity> rotate to position for EX-Turntable
|
case 3: // <I id position activity> | <I id DCC home> - rotate to position for EX-Turntable or create DCC turntable
|
||||||
{
|
{
|
||||||
Turntable *tto = Turntable::get(p[0]);
|
Turntable *tto = Turntable::get(p[0]);
|
||||||
if (!tto) return false;
|
if (p[1] == HASH_KEYWORD_DCC) {
|
||||||
if (!tto->isEXTT()) return false;
|
if (tto || p[2] < 0 || p[2] > 3600) return false;
|
||||||
if (!tto->setPosition(p[0], p[1], p[2])) return false;
|
if (!DCCTurntable::create(p[0])) return false;
|
||||||
|
Turntable *tto = Turntable::get(p[0]);
|
||||||
|
tto->addPosition(0, 0, p[2]);
|
||||||
|
StringFormatter::send(stream, F("<i>\n"));
|
||||||
|
} else {
|
||||||
|
if (!tto) return false;
|
||||||
|
if (!tto->isEXTT()) return false;
|
||||||
|
if (!tto->setPosition(p[0], p[1], p[2])) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 4: // <I id EXTT vpin home> | <I id ADD position value> create an EXTT turntable or add position
|
case 4: // <I id EXTT vpin home> create an EXTT turntable
|
||||||
{
|
{
|
||||||
Turntable *tto = Turntable::get(p[0]);
|
Turntable *tto = Turntable::get(p[0]);
|
||||||
if (p[1] == HASH_KEYWORD_EXTT) {
|
if (p[1] == HASH_KEYWORD_EXTT) {
|
||||||
if (tto) return false;
|
if (tto || p[3] < 0 || p[3] > 3600) return false;
|
||||||
if (!EXTTTurntable::create(p[0], (VPIN)p[2])) return false;
|
if (!EXTTTurntable::create(p[0], (VPIN)p[2])) return false;
|
||||||
Turntable *tto = Turntable::get(p[0]);
|
Turntable *tto = Turntable::get(p[0]);
|
||||||
tto->addPosition(0, p[3]);
|
tto->addPosition(0, 0, p[3]);
|
||||||
} else if (p[1] == HASH_KEYWORD_ADD) {
|
StringFormatter::send(stream, F("<i>\n"));
|
||||||
if (!tto) return false;
|
} else {
|
||||||
tto->addPosition(p[2], p[3]);
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case 5: // <I id ADD position value angle> add a position
|
||||||
|
{
|
||||||
|
Turntable *tto = Turntable::get(p[0]);
|
||||||
|
if (p[1] == HASH_KEYWORD_ADD) {
|
||||||
|
// tto must exist, no more than 48 positions, angle 0 - 3600
|
||||||
|
if (!tto || p[2] > 48 || p[4] < 0 || p[4] > 3600) return false;
|
||||||
|
tto->addPosition(p[2], p[3], p[4]);
|
||||||
StringFormatter::send(stream, F("<i>\n"));
|
StringFormatter::send(stream, F("<i>\n"));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "CommandDistributor.h"
|
#include "CommandDistributor.h"
|
||||||
#include "TrackManager.h"
|
#include "TrackManager.h"
|
||||||
#include "Turntables.h"
|
#include "Turntables.h"
|
||||||
|
#include "IODevice.h"
|
||||||
|
|
||||||
// Command parsing keywords
|
// Command parsing keywords
|
||||||
const int16_t HASH_KEYWORD_EXRAIL=15435;
|
const int16_t HASH_KEYWORD_EXRAIL=15435;
|
||||||
|
@ -248,9 +249,10 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
case OPCODE_DCCTURNTABLE: {
|
case OPCODE_DCCTURNTABLE: {
|
||||||
VPIN id=operand;
|
VPIN id=operand;
|
||||||
|
int home=getOperand(progCounter,1);
|
||||||
setTurntableHiddenState(DCCTurntable::create(id));
|
setTurntableHiddenState(DCCTurntable::create(id));
|
||||||
Turntable *tto=Turntable::get(id);
|
Turntable *tto=Turntable::get(id);
|
||||||
tto->addPosition(0,0);
|
tto->addPosition(0,0,home);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +262,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
||||||
int home=getOperand(progCounter,2);
|
int home=getOperand(progCounter,2);
|
||||||
setTurntableHiddenState(EXTTTurntable::create(id,pin));
|
setTurntableHiddenState(EXTTTurntable::create(id,pin));
|
||||||
Turntable *tto=Turntable::get(id);
|
Turntable *tto=Turntable::get(id);
|
||||||
tto->addPosition(0,home);
|
tto->addPosition(0,0,home);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +270,9 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
||||||
VPIN id=operand;
|
VPIN id=operand;
|
||||||
int position=getOperand(progCounter,1);
|
int position=getOperand(progCounter,1);
|
||||||
int value=getOperand(progCounter,2);
|
int value=getOperand(progCounter,2);
|
||||||
|
int angle=getOperand(progCounter,3);
|
||||||
Turntable *tto=Turntable::get(id);
|
Turntable *tto=Turntable::get(id);
|
||||||
tto->addPosition(position,value);
|
tto->addPosition(position,value,angle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -119,6 +119,7 @@
|
||||||
#undef REV
|
#undef REV
|
||||||
#undef ROSTER
|
#undef ROSTER
|
||||||
#undef ROTATE
|
#undef ROTATE
|
||||||
|
#undef ROTATE_DCC
|
||||||
#undef ROUTE
|
#undef ROUTE
|
||||||
#undef SENDLOCO
|
#undef SENDLOCO
|
||||||
#undef SEQUENCE
|
#undef SEQUENCE
|
||||||
|
@ -174,7 +175,7 @@
|
||||||
#define CALL(route)
|
#define CALL(route)
|
||||||
#define CLOSE(id)
|
#define CLOSE(id)
|
||||||
#define DCC_SIGNAL(id,add,subaddr)
|
#define DCC_SIGNAL(id,add,subaddr)
|
||||||
#define DCC_TURNTABLE(id,description)
|
#define DCC_TURNTABLE(id,home,description)
|
||||||
#define DEACTIVATE(addr,subaddr)
|
#define DEACTIVATE(addr,subaddr)
|
||||||
#define DEACTIVATEL(addr)
|
#define DEACTIVATEL(addr)
|
||||||
#define DELAY(mindelay)
|
#define DELAY(mindelay)
|
||||||
|
@ -252,6 +253,7 @@
|
||||||
#define RETURN
|
#define RETURN
|
||||||
#define REV(speed)
|
#define REV(speed)
|
||||||
#define ROTATE(turntable_id,position,activity)
|
#define ROTATE(turntable_id,position,activity)
|
||||||
|
#define ROTATE_DCC(turntable_id,position)
|
||||||
#define ROSTER(cab,name,funcmap...)
|
#define ROSTER(cab,name,funcmap...)
|
||||||
#define ROUTE(id,description)
|
#define ROUTE(id,description)
|
||||||
#define SENDLOCO(cab,route)
|
#define SENDLOCO(cab,route)
|
||||||
|
@ -276,7 +278,7 @@
|
||||||
#define START(route)
|
#define START(route)
|
||||||
#define STOP
|
#define STOP
|
||||||
#define THROW(id)
|
#define THROW(id)
|
||||||
#define TT_ADDPOSITION(turntable_id,position,value,description)
|
#define TT_ADDPOSITION(turntable_id,position,value,angle,description...)
|
||||||
#define TURNOUT(id,addr,subaddr,description...)
|
#define TURNOUT(id,addr,subaddr,description...)
|
||||||
#define TURNOUTL(id,addr,description...)
|
#define TURNOUTL(id,addr,description...)
|
||||||
#define UNJOIN
|
#define UNJOIN
|
||||||
|
|
|
@ -192,7 +192,7 @@ const FSH * RMFT2::getTurnoutDescription(int16_t turnoutid) {
|
||||||
// Pass to get turntable descriptions (optional)
|
// Pass to get turntable descriptions (optional)
|
||||||
#include "EXRAIL2MacroReset.h"
|
#include "EXRAIL2MacroReset.h"
|
||||||
#undef DCC_TURNTABLE
|
#undef DCC_TURNTABLE
|
||||||
#define DCC_TURNTABLE(id,description...) O_DESC(id,description)
|
#define DCC_TURNTABLE(id,home,description...) O_DESC(id,description)
|
||||||
#undef EXTT_TURNTABLE
|
#undef EXTT_TURNTABLE
|
||||||
#define EXTT_TURNTABLE(id,vpin,home,description...) O_DESC(id,description)
|
#define EXTT_TURNTABLE(id,vpin,home,description...) O_DESC(id,description)
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ const FSH * RMFT2::getTurntableDescription(int16_t turntableId) {
|
||||||
// Pass to get turntable position descriptions (optional)
|
// Pass to get turntable position descriptions (optional)
|
||||||
#include "EXRAIL2MacroReset.h"
|
#include "EXRAIL2MacroReset.h"
|
||||||
#undef TT_ADDPOSITION
|
#undef TT_ADDPOSITION
|
||||||
#define TT_ADDPOSITION(turntable_id,position,value,description...) T_DESC(turntable_id,position,description)
|
#define TT_ADDPOSITION(turntable_id,position,value,home,description...) T_DESC(turntable_id,position,description)
|
||||||
|
|
||||||
const FSH * RMFT2::getTurntablePositionDescription(int16_t turntableId, uint8_t positionId) {
|
const FSH * RMFT2::getTurntablePositionDescription(int16_t turntableId, uint8_t positionId) {
|
||||||
#include "myAutomation.h"
|
#include "myAutomation.h"
|
||||||
|
@ -296,7 +296,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = {
|
||||||
#define CALL(route) OPCODE_CALL,V(route),
|
#define CALL(route) OPCODE_CALL,V(route),
|
||||||
#define CLOSE(id) OPCODE_CLOSE,V(id),
|
#define CLOSE(id) OPCODE_CLOSE,V(id),
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
#define DCC_TURNTABLE(id,description...) OPCODE_DCCTURNTABLE,V(id),
|
#define DCC_TURNTABLE(id,home,description...) OPCODE_DCCTURNTABLE,V(id),OPCODE_PAD,V(home),
|
||||||
#endif
|
#endif
|
||||||
#define DEACTIVATE(addr,subaddr) OPCODE_DCCACTIVATE,V(addr<<3 | subaddr<<1),
|
#define DEACTIVATE(addr,subaddr) OPCODE_DCCACTIVATE,V(addr<<3 | subaddr<<1),
|
||||||
#define DEACTIVATEL(addr) OPCODE_DCCACTIVATE,V((addr+3)<<1),
|
#define DEACTIVATEL(addr) OPCODE_DCCACTIVATE,V((addr+3)<<1),
|
||||||
|
@ -383,7 +383,8 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = {
|
||||||
#define REV(speed) OPCODE_REV,V(speed),
|
#define REV(speed) OPCODE_REV,V(speed),
|
||||||
#define ROSTER(cabid,name,funcmap...)
|
#define ROSTER(cabid,name,funcmap...)
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
#define ROTATE(id,position,activity) OPCODE_ROTATE,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(activity),
|
#define ROTATE(id,position,activity) OPCODE_ROTATE,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(EXTurntable::activity),
|
||||||
|
#define ROTATE_DCC(id,position) OPCODE_ROTATE,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(0),
|
||||||
#endif
|
#endif
|
||||||
#define ROUTE(id, description) OPCODE_ROUTE, V(id),
|
#define ROUTE(id, description) OPCODE_ROUTE, V(id),
|
||||||
#define SENDLOCO(cab,route) OPCODE_SENDLOCO,V(cab),OPCODE_PAD,V(route),
|
#define SENDLOCO(cab,route) OPCODE_SENDLOCO,V(cab),OPCODE_PAD,V(route),
|
||||||
|
@ -409,7 +410,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = {
|
||||||
#define STOP OPCODE_SPEED,V(0),
|
#define STOP OPCODE_SPEED,V(0),
|
||||||
#define THROW(id) OPCODE_THROW,V(id),
|
#define THROW(id) OPCODE_THROW,V(id),
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
#define TT_ADDPOSITION(id,position,value,description...) OPCODE_TTADDPOSITION,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(value),
|
#define TT_ADDPOSITION(id,position,value,angle,description...) OPCODE_TTADDPOSITION,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(value),OPCODE_PAD,V(angle),
|
||||||
#endif
|
#endif
|
||||||
#define TURNOUT(id,addr,subaddr,description...) OPCODE_TURNOUT,V(id),OPCODE_PAD,V(addr),OPCODE_PAD,V(subaddr),
|
#define TURNOUT(id,addr,subaddr,description...) OPCODE_TURNOUT,V(id),OPCODE_PAD,V(addr),OPCODE_PAD,V(subaddr),
|
||||||
#define TURNOUTL(id,addr,description...) TURNOUT(id,(addr-1)/4+1,(addr-1)%4, description)
|
#define TURNOUTL(id,addr,description...) TURNOUT(id,(addr-1)/4+1,(addr-1)%4, description)
|
||||||
|
|
|
@ -58,8 +58,8 @@ void Turntable::add(Turntable *tto) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a position
|
// Add a position
|
||||||
void Turntable::addPosition(uint8_t idx, uint16_t value) {
|
void Turntable::addPosition(uint8_t idx, uint16_t value, uint16_t angle) {
|
||||||
_turntablePositions.insert(idx, value);
|
_turntablePositions.insert(idx, value, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value for position
|
// Get value for position
|
||||||
|
@ -74,6 +74,18 @@ uint16_t Turntable::getPositionValue(uint8_t position) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get value for position
|
||||||
|
uint16_t Turntable::getPositionAngle(uint8_t position) {
|
||||||
|
TurntablePosition* currentPosition = _turntablePositions.getHead();
|
||||||
|
while (currentPosition) {
|
||||||
|
if (currentPosition->index == position) {
|
||||||
|
return currentPosition->angle;
|
||||||
|
}
|
||||||
|
currentPosition = currentPosition->next;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the count of positions associated with the turntable
|
// Get the count of positions associated with the turntable
|
||||||
uint8_t Turntable::getPositionCount() {
|
uint8_t Turntable::getPositionCount() {
|
||||||
TurntablePosition* currentPosition = _turntablePositions.getHead();
|
TurntablePosition* currentPosition = _turntablePositions.getHead();
|
||||||
|
@ -115,6 +127,7 @@ uint8_t Turntable::getPosition(uint16_t id) {
|
||||||
return tto->getPosition();
|
return tto->getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Got the moving state of the specified turntable
|
||||||
bool Turntable::ttMoving(uint16_t id) {
|
bool Turntable::ttMoving(uint16_t id) {
|
||||||
Turntable *tto = get(id);
|
Turntable *tto = get(id);
|
||||||
if (!tto) return false;
|
if (!tto) return false;
|
||||||
|
|
13
Turntables.h
13
Turntables.h
|
@ -36,9 +36,6 @@ enum {
|
||||||
TURNTABLE_DCC = 1,
|
TURNTABLE_DCC = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callback needs to return a bool: 1 = moving, 0 = stopped
|
|
||||||
typedef void (*EXTT_CALLBACK)(bool moving);
|
|
||||||
|
|
||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
* Turntable positions.
|
* Turntable positions.
|
||||||
*
|
*
|
||||||
|
@ -46,17 +43,18 @@ typedef void (*EXTT_CALLBACK)(bool moving);
|
||||||
struct TurntablePosition {
|
struct TurntablePosition {
|
||||||
uint8_t index;
|
uint8_t index;
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
|
uint16_t angle;
|
||||||
TurntablePosition* next;
|
TurntablePosition* next;
|
||||||
|
|
||||||
TurntablePosition(uint8_t idx, uint16_t value) : index(idx), data(value), next(nullptr) {}
|
TurntablePosition(uint8_t idx, uint16_t value, uint16_t angle) : index(idx), data(value), angle(angle), next(nullptr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TurntablePositionList {
|
class TurntablePositionList {
|
||||||
public:
|
public:
|
||||||
TurntablePositionList() : head(nullptr) {}
|
TurntablePositionList() : head(nullptr) {}
|
||||||
|
|
||||||
void insert(uint8_t idx, uint16_t value) {
|
void insert(uint8_t idx, uint16_t value, uint16_t angle) {
|
||||||
TurntablePosition* newPosition = new TurntablePosition(idx, value);
|
TurntablePosition* newPosition = new TurntablePosition(idx, value, angle);
|
||||||
if(!head) {
|
if(!head) {
|
||||||
head = newPosition;
|
head = newPosition;
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,8 +156,9 @@ public:
|
||||||
inline uint16_t getId() { return _turntableData.id; }
|
inline uint16_t getId() { return _turntableData.id; }
|
||||||
inline Turntable *next() { return _nextTurntable; }
|
inline Turntable *next() { return _nextTurntable; }
|
||||||
void printState(Print *stream);
|
void printState(Print *stream);
|
||||||
void addPosition(uint8_t idx, uint16_t value);
|
void addPosition(uint8_t idx, uint16_t value, uint16_t angle);
|
||||||
uint16_t getPositionValue(uint8_t position);
|
uint16_t getPositionValue(uint8_t position);
|
||||||
|
uint16_t getPositionAngle(uint8_t position);
|
||||||
uint8_t getPositionCount();
|
uint8_t getPositionCount();
|
||||||
bool isMoving() { return _isMoving; }
|
bool isMoving() { return _isMoving; }
|
||||||
void setMoving(bool moving) { _isMoving=moving; }
|
void setMoving(bool moving) { _isMoving=moving; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user