Z21ServerEmulator/z21library/z21.h

251 lines
12 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
z21.h - library for Z21 mobile protocoll
Copyright (c) 2013-2022 Philipp Gahtow All right reserved.
ROCO Z21 LAN Protocol for Arduino.
Notice:
- analyse the data and give back the content and a answer
Grundlage: Z21 LAN Protokoll Spezifikation V1.12
Änderungen:
- 23.09.15 Anpassung LAN_LOCONET_DETECTOR
Fehlerbeseitigung bei der LAN Prüfsumme
Anpassung LAN_LOCONET_DISPATCH
- 14.07.16 add S88 Gruppenindex for request
- 22.08.16 add POM read notify
- 19.12.16 add CV return value for Service Mode
- 27.12.16 add CV no ACK and CV Short Circuit
- 15.03.17 add System Information
- 03.04.17 fix LAN_X_SET_LOCO_FUNCTION in DB3 type and index
- 14.04.17 add EEPROM and store Z21 configuration (EEPROM: 50-75)
- 19.06.17 add FW Version 1.28, 1.29 and 1.30
- 06.08.17 add support for Arduino DUE
- 27.08.17 fix speed step setting
- 09.01.18 adjust POM write Byte and Bit
- 21.01.18 adjust notifyz21LNdispatch to long Adr
- 04.02.18 fix LocoNet dispatch
- 22.10.18 add loco busy return
- 02.11.18 adjust returnLocoStateFull with addition non broadcast when requestion only information
- 04.11.18 fix EthSend handel of message with client == 0 and Broadcast with client and without
- 10.05.20 add message LAN_GET_LOCOMODE and LAN_GET_TURNOUTMODE
- 04.08.20 fix POM set CV result
- 17.12.20 add support for ESP32 and adjust ESP8266
- 01.03.21 set default EEPROM MainV and ProgV to 20V
- 03.03.21 add new Z21 spezifications v1.10
- 21.03.21 add request for client identification (ip-hash) and store this plus BC-Flag in EEPROM
- 30.03.21 fix connecting problem WDP with reporting railpower when request status
- 11.06.21 add NVS on ESP32 to store EEPROM data
- 30.09.21 fix storage data in Ethsend with correct datalength; fix problem with LAN_X_GET_TURNOUT_INFO to return feedbacks also when LAN_X_SET_TURNOUT is called!
- 06.11.21 fix EEPROM store BCFlags with IP Hash value. Use EEPROM value from 512 up to 736.
- 16.11.21 add sending data to client only with "Z21bcNone", if client set and BC-Flag set (not "Z21bcNone") then don't inform the client!
- 14.12.21 limit max packet size for Z21 LocoNet tunnel data to 20 bytes!
- 03.02.22 fix setCANDetector() data values with 16bit
- 10.02.22 add LAN_X_CV_POM_ACCESSORY statements
- 24.04.22 add SystemState.Capabilities for feature report to clients (FW Version 1.42)
modify LAN_X_LOCO_INFO to FW Version 1.42
- 25.04.22 add LAN_X_SET_LOCO_FUNCTION_GROUP and LAN_X_SET_LOCO_BINARY_STATE
fix SET_EXT_ACCESSORY and EXT_ACCESSORY_INFO
- 29.04.22 add WLANMaus CV Read and write special functions
*/
// include types & constants of Wiring core API
#if defined(WIRING)
#include <Wiring.h>
#elif ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
//--------------------------------------------------------------
#define z21Port 21105 // local port to listen on
//**************************************************************
//#define SERIALDEBUG //Serial Debug
#if defined(SERIALDEBUG)
#define ZDebug Serial //Port for the Debugging
#endif
//**************************************************************
//Firmware-Version der Z21:
#define z21FWVersionMSB 0x01
#define z21FWVersionLSB 0x42
/*
HwType:
#define D_HWT_Z21_OLD 0x00000200 // „schwarze Z21” (Hardware-Variante ab 2012)
#define D_HWT_Z21_NEW 0x00000201 // „schwarze Z21”(Hardware-Variante ab 2013)
#define D_HWT_SMARTRAIL 0x00000202 // SmartRail (ab 2012)
#define D_HWT_z21_SMALL 0x00000203 // „weiße z21” Starterset-Variante (ab 2013)
#define D_HWT_z21_START 0x00000204 // „z21 start” Starterset-Variante (ab 2016)
#define D_HWT_Z21_XL 0x00000211 // 10870 „Z21 XL Series” (ab 2020)
#define D_HWT_SINGLE_BOOSTER 0x00000205 // 10806 „Z21 Single Booster” (zLink)
#define D_HWT_DUAL_BOOSTER 0x00000206 // 10807 „Z21 Dual Booster” (zLink)
#define D_HWT_Z21_SWITCH_DECODER 0x00000301 // 10836 „Z21 SwitchDecoder” (zLink)
#define D_HWT_Z21_SIGNAL_DECODER 0x00000302 // 10836 „Z21 SignalDecoder” (zLink)
*/
//Hardware-Typ: 0x00000211 // 10870 „Z21 XL Series” (ab 2020)
#define z21HWTypeMSB 0x02
#define z21HWTypeLSB 0x11
//Seriennummer inside EEPROM:
#define CONFz21SnMSB 0 //0x01
#define CONFz21SnLSB 1 //0xE8
//**************************************************************
//Store Z21 configuration inside EEPROM:
#define CONF1STORE 50 //(10x Byte) - Prog, RailCom, etc.
#define CONF2STORE 60 //(15x Byte) - Voltage: Prog, Rail, etc.
#define CLIENTHASHSTORE 0x200 //512 Start where Client-Hash is stored
//--------------------------------------------------------------
//certain global XPressnet status indicators:
#define csNormal 0x00 // Normal Operation Resumed ist eingeschaltet
#define csEmergencyStop 0x01 // Der Nothalt ist eingeschaltet
#define csTrackVoltageOff 0x02 // Die Gleisspannung ist abgeschaltet
#define csShortCircuit 0x04 // Kurzschluss
#define csServiceMode 0x08 // Der Programmiermodus ist aktiv - Service Mode
//Bitmask CentralStateEx:
#define cseHighTemperature 0x01 // zu hohe Temperatur
#define csePowerLost 0x02 // zu geringe Eingangsspannung
#define cseShortCircuitExternal 0x04 // am externen Booster-Ausgang
#define cseShortCircuitInternal 0x08 // am Hauptgleis oder Programmiergleis
//--------------------------------------------------------------
#define z21clientMAX 30 //Speichergröße für IP-Adressen
#define z21ActTimeIP 20 //Aktivhaltung einer IP für (sec./2)
#define z21IPinterval 2000 //interval at milliseconds
//DCC Speed Steps
#define DCCSTEP14 0x01
#define DCCSTEP28 0x02
#define DCCSTEP128 0x03
struct TypeActIP {
byte client; // Byte client
byte BCFlag; //BoadCastFlag - see Z21type.h
byte time; //Zeit
uint16_t adr; //Loco control Adr
};
// library interface description
class z21Class
{
// user-accessible "public" interface
public:
z21Class(void); //Constuctor
void receive(uint8_t client, uint8_t *packet); //Prüfe auf neue Ethernet Daten
void setPower(byte state); //Zustand Gleisspannung Melden
byte getPower(); //Zusand Gleisspannung ausgeben
void setCVPOMBYTE (uint16_t CVAdr, uint8_t value); //POM write byte return
void setLocoStateExt (int Adr); //send Loco state to BC
unsigned long getz21BcFlag (byte flag); //Convert local stored flag back into a Z21 Flag
void setS88Data(byte *data); //return state of S88 sensors
void setLNDetector(uint8_t client, byte *data, byte DataLen); //return state from LN detector
bool setLNMessage(byte *data, byte DataLen, byte bcType, bool TX); //return LN Message
void setCANDetector(uint16_t NID, uint16_t Adr, uint8_t port, uint8_t typ, uint16_t v1, uint16_t v2); //state from CAN detector
void setTrntInfo(uint16_t Adr, bool State); //Return the state of accessory
void setExtACCInfo(uint16_t Adr, byte State, bool Status = 0x00); //Return EXT Accessory INFO
void setCVReturn (uint16_t CV, uint8_t value); //Return CV Value for Programming
void setCVNack(); //Return no ACK from Decoder
void setCVNackSC(); //Return Short while Programming
void sendSystemInfo(byte client, uint16_t maincurrent, uint16_t mainvoltage, uint16_t temp); //Send to all clients that request via BC the System Information
// library-accessible "private" interface
private:
//Variables:
byte Railpower; //state of the railpower
long z21IPpreviousMillis; // will store last time of IP decount updated
TypeActIP ActIP[z21clientMAX]; //Speicherarray für IPs
//Functions:
void returnLocoStateFull (byte client, uint16_t Adr, bool bc); //Antwort auf Statusabfrage
void EthSend (byte client, unsigned int DataLen, unsigned int Header, byte *dataString, boolean withXOR, byte BC);
byte getLocalBcFlag (unsigned long flag); //Convert Z21 LAN BC flag to local stored flag
void clearIP (byte pos); //delete the stored client
void clearIPSlots(); //delete all stored clients
void clearIPSlot(byte client); //delete a client
byte addIPToSlot (byte client, byte BCFlag);
void setOtherSlotBusy(byte slot);
void addBusySlot (byte client, uint16_t adr);
void reqLocoBusy (uint16_t adr);
byte getEEPROMBCFlagIndex(); //return the length of BC-Flag store
void setEEPROMBCFlag(byte IPHash, byte BCFlag); //add BC-Flag to store
byte findEEPROMBCFlag(byte IPHash); //read the BC-Flag for this client
uint8_t LAST_EXTACC_msg = 0x00; //for LAN_X_GET_EXT_ACCESSORY_INFO
bool LAST_EXTACC_received = false; //already had any EXTACC Message?
};
#if defined (__cplusplus)
extern "C" {
#endif
extern void notifyz21getSystemInfo(uint8_t client) __attribute__((weak));
extern void notifyz21EthSend(uint8_t client, uint8_t *data) __attribute__((weak));
extern void notifyz21LNdetector(uint8_t client, uint8_t typ, uint16_t Adr) __attribute__((weak));
extern uint8_t notifyz21LNdispatch(uint16_t Adr) __attribute__((weak));
extern void notifyz21LNSendPacket(uint8_t *data, uint8_t length) __attribute__((weak));
extern void notifyz21CANdetector(uint8_t client, uint8_t typ, uint16_t ID) __attribute__((weak));
extern void notifyz21RailPower(uint8_t State ) __attribute__((weak));
extern void notifyz21CVREAD(uint8_t cvAdrMSB, uint8_t cvAdrLSB) __attribute__((weak));
extern void notifyz21CVWRITE(uint8_t cvAdrMSB, uint8_t cvAdrLSB, uint8_t value) __attribute__((weak));
extern void notifyz21CVPOMWRITEBYTE(uint16_t Adr, uint16_t cvAdr, uint8_t value) __attribute__((weak));
extern void notifyz21CVPOMWRITEBIT(uint16_t Adr, uint16_t cvAdr, uint8_t value) __attribute__((weak));
extern void notifyz21CVPOMREADBYTE(uint16_t Adr, uint16_t cvAdr) __attribute__((weak));
extern void notifyz21CVPOMACCWRITEBYTE(uint16_t Adr, uint16_t cvAdr, uint8_t value) __attribute__((weak));
extern void notifyz21CVPOMACCWRITEBIT(uint16_t Adr, uint16_t cvAdr, uint8_t value) __attribute__((weak));
extern void notifyz21CVPOMACCREADBYTE(uint16_t Adr, uint16_t cvAdr) __attribute__((weak));
extern uint8_t notifyz21AccessoryInfo(uint16_t Adr) __attribute__((weak));
extern void notifyz21Accessory(uint16_t Adr, bool state, bool active) __attribute__((weak));
extern void notifyz21ExtAccessory(uint16_t Adr, byte state) __attribute__((weak));
extern void notifyz21LocoState(uint16_t Adr, uint8_t data[]) __attribute__((weak));
extern void notifyz21LocoFkt(uint16_t Adr, uint8_t type, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt0to4(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt5to8(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt9to12(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt13to20(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt21to28(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt29to36(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt37to44(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt45to52(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt53to60(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFkt61to68(uint16_t Adr, uint8_t fkt) __attribute__((weak));
extern void notifyz21LocoFktExt(uint16_t Adr, uint8_t low, uint8_t high) __attribute__((weak));
extern void notifyz21LocoSpeed(uint16_t Adr, uint8_t speed, uint8_t steps) __attribute__((weak));
extern void notifyz21S88Data(uint8_t gIndex) __attribute__((weak)); //return last state S88 Data for the Client!
extern uint16_t notifyz21Railcom() __attribute__((weak)); //return global Railcom Adr
extern void notifyz21UpdateConf() __attribute__((weak)); //information for DCC via EEPROM (RailCom, ProgMode,...)
extern uint8_t notifyz21ClientHash(uint8_t client) __attribute__((weak));
#if defined (__cplusplus)
}
#endif