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/>.
|
|
|
|
*/
|
2021-08-03 23:12:25 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2020-06-03 15:26:49 +02:00
|
|
|
#ifndef Turnouts_h
|
|
|
|
#define Turnouts_h
|
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include "DCC.h"
|
2021-03-23 15:37:05 +01:00
|
|
|
#include "LCN.h"
|
2021-08-03 23:12:25 +02:00
|
|
|
#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
|
2020-06-03 15:26:49 +02:00
|
|
|
|
2021-08-03 23:12:25 +02:00
|
|
|
// 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.
|
2020-06-03 15:26:49 +02:00
|
|
|
struct TurnoutData {
|
2021-08-03 23:12:25 +02:00
|
|
|
// 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;
|
|
|
|
};
|
2020-06-03 15:26:49 +02:00
|
|
|
};
|
|
|
|
|
2020-07-23 13:48:38 +02:00
|
|
|
class Turnout {
|
2021-08-03 23:12:25 +02:00
|
|
|
public:
|
2020-06-03 15:26:49 +02:00
|
|
|
static Turnout *firstTurnout;
|
2020-08-20 13:38:09 +02:00
|
|
|
static int turnoutlistHash;
|
2020-06-23 18:43:50 +02:00
|
|
|
TurnoutData data;
|
2020-06-03 15:26:49 +02:00
|
|
|
Turnout *nextTurnout;
|
2021-08-03 23:12:25 +02:00
|
|
|
static bool activate(int n, bool state);
|
2020-06-03 15:26:49 +02:00
|
|
|
static Turnout* get(int);
|
|
|
|
static bool remove(int);
|
2020-07-23 18:34:35 +02:00
|
|
|
static bool isActive(int);
|
2021-08-03 23:12:25 +02:00
|
|
|
static void setActive(int n, bool state);
|
2020-06-03 15:26:49 +02:00
|
|
|
static void load();
|
|
|
|
static void store();
|
2021-08-03 23:12:25 +02:00
|
|
|
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[]);
|
2020-06-23 18:43:50 +02:00
|
|
|
static Turnout *create(int id);
|
2020-07-23 13:48:38 +02:00
|
|
|
void activate(bool state);
|
2021-08-03 23:12:25 +02:00
|
|
|
void setActive(bool state);
|
|
|
|
bool isActive();
|
2021-01-04 16:57:03 +01:00
|
|
|
static void printAll(Print *);
|
2021-08-03 23:12:25 +02:00
|
|
|
void print(Print *stream);
|
2020-10-03 14:07:25 +02:00
|
|
|
#ifdef EESTOREDEBUG
|
2021-08-03 23:12:25 +02:00
|
|
|
static void print(Turnout *tt);
|
2020-10-03 14:07:25 +02:00
|
|
|
#endif
|
2021-05-07 01:12:33 +02:00
|
|
|
private:
|
|
|
|
int num; // EEPROM address of tStatus in TurnoutData struct, or zero if not stored.
|
2020-06-03 15:26:49 +02:00
|
|
|
}; // Turnout
|
|
|
|
|
|
|
|
#endif
|