1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

Narrowing Turnout publics

This commit is contained in:
Asbelos 2021-08-18 18:55:22 +01:00
parent 9dacd24d27
commit 36f6e2f9ce
7 changed files with 66 additions and 36 deletions

View File

@ -672,14 +672,10 @@ bool DCCEXParser::parseT(Print *stream, int16_t params, int16_t p[])
StringFormatter::send(stream, F("<O>\n"));
return true;
case 2: // <T id 0|1> activate turnout
{
Turnout *tt = Turnout::get(p[0]);
if (!tt)
return false;
tt->activate(p[1]);
StringFormatter::send(stream, F("<H %d %d>\n"), p[0], tt->data.active);
}
case 2: // <T id 0|1> turnout 0=CLOSE,1=THROW
if (p[1]>1 || p[1]<0 ) return false;
if (!Turnout::setClosed(p[0],p[1]==0)) return false;
StringFormatter::send(stream, F("<H %d %d>\n"), p[0], p[1]);
return true;
default: // Anything else is handled by Turnout class.

View File

@ -50,7 +50,7 @@ void LCN::loop() {
if (Diag::LCN) DIAG(F("LCN IN %d%c"),id,(char)ch);
Turnout * tt = Turnout::get(id);
if (!tt) tt=Turnout::createLCN(id);
tt->setActive(ch=='t');
Turnout::setClosedStateOnly(id,ch=='t');
Turnout::turnoutlistHash++; // signals ED update of turnout data
id = 0;
}

View File

@ -382,11 +382,11 @@ void RMFT2::loop2() {
switch ((OPCODE)opcode) {
case OPCODE_THROW:
Turnout::activate(operand, false);
Turnout::setClosed(operand, false);
break;
case OPCODE_CLOSE:
Turnout::activate(operand, true);
Turnout::setClosed(operand, true);
break;
case OPCODE_REV:
@ -666,8 +666,8 @@ void RMFT2::kill(const FSH * reason, int operand) {
return;
}
}
void RMFT2::turnoutEvent(VPIN id, bool state) {
byte huntFor=state ? OPCODE_ONCLOSE : OPCODE_ONTHROW ;
void RMFT2::turnoutEvent(VPIN id, bool closed) {
byte huntFor=closed ? OPCODE_ONCLOSE : OPCODE_ONTHROW ;
// caution hides class progCounter;
for (int progCounter=0;; SKIPOP){
byte opcode=GET_OPCODE;

View File

@ -68,7 +68,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
static void readLocoCallback(int cv);
static void emitWithrottleRouteList(Print* stream);
static void createNewTask(int route, uint16_t cab);
static void turnoutEvent(VPIN id, bool thrown);
static void turnoutEvent(VPIN id, bool closed);
private:
static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int p[]);
static bool parseSlash(Print * stream, byte & paramCount, int p[]) ;

View File

@ -18,6 +18,12 @@
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
// >>>>>> ATTENTION: This class requires major cleaning.
// The public interface has been narrowed to avoid the ambuguity of "activated".
//#define EESTOREDEBUG
#include "defines.h"
#include "Turnouts.h"
@ -40,6 +46,10 @@ enum unit8_t {
TURNOUT_LCN = 4,
};
///////////////////////////////////////////////////////////////////////////////
// Static function to print all Turnout states to stream in form "<H id state>"
@ -82,10 +92,25 @@ void Turnout::print(Print *stream){
}
}
// Public interface to turnout throw/close
bool Turnout::setClosed(int id, bool closed) {
// hides the internal activate argument to a single place
return activate(id, closed? false: true ); /// Needs cleaning up
}
bool Turnout::isClosed(int id) {
// hides the internal activate argument to a single place
return !isActive(id); /// Needs cleaning up
}
int Turnout::getId() {
return data.id;
}
///////////////////////////////////////////////////////////////////////////////
// Static function to activate/deactivate Turnout with ID 'n'.
// Returns false if turnout not found.
bool Turnout::activate(int n, bool state){
Turnout * tt=get(n);
if (!tt) return false;
@ -145,7 +170,7 @@ void Turnout::activate(bool state) {
EEPROM.put(num, data.tStatus);
#if defined(RMFT_ACTIVE)
RMFT2::turnoutEvent(data.id, state);
RMFT2::turnoutEvent(data.id, !state);
#endif
}

View File

@ -33,6 +33,7 @@
#include "LCN.h"
#include "IODevice.h"
const byte STATUS_ACTIVE=0x80; // Flag as activated in tStatus field
const byte STATUS_TYPE = 0x7f; // Mask for turnout type in tStatus field
@ -91,13 +92,13 @@ class Turnout {
public:
static Turnout *firstTurnout;
static int turnoutlistHash;
TurnoutData data;
Turnout *nextTurnout;
static bool activate(int n, bool state);
static Turnout* get(int);
static bool remove(int);
static bool isActive(int);
static void setActive(int n, bool state);
static bool isClosed(int);
static bool setClosed(int n, bool closed); // return false if not found.
static void setClosedStateOnly(int n, bool closed);
int getId();
static void load();
static void store();
static Turnout *createServo(int id , VPIN vpin , uint16_t activeAngle, uint16_t inactiveAngle, uint8_t profile=1, uint8_t initialState=0);
@ -106,9 +107,6 @@ public:
static Turnout *createLCN(int id, uint8_t initialState=0);
static Turnout *create(int id, int params, int16_t p[]);
static Turnout *create(int id);
void activate(bool state);
void setActive(bool state);
bool isActive();
static void printAll(Print *);
void print(Print *stream);
#ifdef EESTOREDEBUG
@ -116,6 +114,12 @@ public:
#endif
private:
int num; // EEPROM address of tStatus in TurnoutData struct, or zero if not stored.
}; // Turnout
TurnoutData data;
static bool activate(int n, bool thrown);
static bool isActive(int);
bool isActive();
void activate(bool state);
void setActive(bool state);
}; // Turnout
#endif

View File

@ -121,7 +121,8 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
if (turnoutListHash != Turnout::turnoutlistHash) {
StringFormatter::send(stream,F("PTL"));
for(Turnout *tt=Turnout::firstTurnout;tt!=NULL;tt=tt->nextTurnout){
StringFormatter::send(stream,F("]\\[%d}|{%d}|{%c"), tt->data.id, tt->data.id, Turnout::isActive(tt->data.id)?'4':'2');
int id=tt->getId();
StringFormatter::send(stream,F("]\\[%d}|{%d}|{%c"), id, id, Turnout::isClosed(id)?'2':'4');
}
StringFormatter::send(stream,F("\n"));
turnoutListHash = Turnout::turnoutlistHash; // keep a copy of hash for later comparison
@ -160,7 +161,6 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
#endif
else if (cmd[1]=='T' && cmd[2]=='A') { // PTA accessory toggle
int id=getInt(cmd+4);
byte newstate=2; // newstate can be 0,1 or 2. 2 is "invalid".
Turnout * tt=Turnout::get(id);
if (!tt) {
// If turnout does not exist, create it
@ -170,17 +170,22 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
StringFormatter::send(stream, F("HmTurnout %d created\n"),id);
}
switch (cmd[3]) {
// T and C according to RCN-213 where 0 is Stop, Red, Thrown, Diverging.
case 'T': newstate=0; break;
case 'C': newstate=1; break;
case '2': newstate=!Turnout::isActive(id); break;
default : /* newstate still invalid */ break;
// T and C according to RCN-213 where 0 is Stop, Red, Thrown, Diverging.
case 'T':
Turnout::setClosed(id,false);
break;
case 'C':
Turnout::setClosed(id,true);
break;
case '2':
Turnout::setClosed(id,!Turnout::isClosed(id));
break;
default :
Turnout::setClosed(id,true);
break;
}
if (newstate != 2) {
Turnout::activate(id,newstate);
StringFormatter::send(stream, F("PTA%c%d\n"),newstate?'4':'2',id );
}
}
StringFormatter::send(stream, F("PTA%c%d\n"),Turnout::isClosed(id)?'2':'4',id );
}
break;
case 'N': // Heartbeat (2), only send if connection completed by 'HU' message
if (initSent) {
@ -194,7 +199,7 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
if (cmd[1] == 'U') {
StringFormatter::send(stream,F("VN2.0\nHTDCC-EX\nRL0\n"));
StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA));
StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[Closed}|{2]\\[Thrown}|{4\n"));
StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[THROW}|{2]\\[CLOSE}|{4\n"));
StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON);
lastPowerState = (DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); //remember power state sent for comparison later
StringFormatter::send(stream,F("*%d\n"),HEARTBEAT_SECONDS);