1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-26 17:46:14 +01:00
CommandStation-EX/Turnouts.h

126 lines
3.8 KiB
C
Raw Permalink Normal View History

2020-07-03 18:35:02 +02:00
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of Asbelos DCC API
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
/*
* Turnout data is stored in a structure whose length depends on the
* type of turnout. There is a common header of 3 bytes, followed by
* 2 bytes for DCC turnout, 5 bytes for servo turnout, 2 bytes for a
* VPIN turnout, or zero bytes for an LCN turnout.
* The variable length allows the limited space in EEPROM to be used effectively.
*/
#ifndef Turnouts_h
#define Turnouts_h
#include <Arduino.h>
#include "DCC.h"
#include "LCN.h"
#include "IODevice.h"
2021-08-18 19:55:22 +02:00
const byte STATUS_ACTIVE=0x80; // Flag as activated in tStatus field
const byte STATUS_TYPE = 0x7f; // Mask for turnout type in tStatus field
// The struct 'header' is used to determine the length of the
// overlaid data so must be at least as long as the anonymous fields it
// is overlaid with.
struct TurnoutData {
// Header common to all turnouts
union {
struct {
int id;
uint8_t tStatus;
uint8_t size;
} header;
struct {
int id;
union {
uint8_t tStatus;
struct {
uint8_t active: 1;
uint8_t type: 5;
uint8_t :2;
};
};
uint8_t size; // set to actual total length of used structure
};
};
// Turnout-type-specific structure elements, different length depending
// on turnout type. This allows the data to be packed efficiently
// in the EEPROM.
union {
struct {
// DCC address (Address in bits 15-2, subaddress in bits 1-0
uint16_t address; // CS currently supports linear address 1-2048
// That's DCC accessory address 1-512 and subaddress 0-3.
} dccAccessoryData;
struct {
VPIN vpin;
uint16_t activePosition : 12; // 0-4095
uint16_t inactivePosition : 12; // 0-4095
uint8_t profile;
} servoData;
struct {
} lcnData;
struct {
VPIN vpin;
} vpinData;
};
};
class Turnout {
public:
static Turnout *firstTurnout;
2020-08-20 13:38:09 +02:00
static int turnoutlistHash;
Turnout *nextTurnout;
static Turnout* get(int);
static bool remove(int);
2021-08-18 19:55:22 +02:00
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);
static Turnout *createVpin(int id, VPIN vpin, uint8_t initialState=0);
static Turnout *createDCC(int id, uint16_t address, uint8_t subAddress);
static Turnout *createLCN(int id, uint8_t initialState=0);
static Turnout *create(int id, int params, int16_t p[]);
static Turnout *create(int id);
static void printAll(Print *);
void print(Print *stream);
#ifdef EESTOREDEBUG
static void print(Turnout *tt);
#endif
private:
int num; // EEPROM address of tStatus in TurnoutData struct, or zero if not stored.
2021-08-18 19:55:22 +02:00
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