[cbus] added CBUS protocol opcodes

Dieser Commit ist enthalten in:
Reinder Feenstra 2026-02-15 13:44:23 +01:00
Ursprung 8d7e1d2a46
Commit f3363133c6
2 geänderte Dateien mit 348 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,172 @@
/**
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* Copyright (C) 2026 Reinder Feenstra
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_CBUS_CBUSOPCODE_HPP
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_CBUS_CBUSOPCODE_HPP
#include <cstdint>
namespace CBUS {
//! \brief CBUS OpCode
//! \see https://github.com/cbus-traincontrol/cbus-traincontrol.github.io/blob/main/CBUS%20Developers%20Guide%206c.pdf
//!
enum class OpCode : uint8_t
{
// 00-1F – 0 data bytes packets:
ACK = 0x00, //!< General Acknowledgement
NAK = 0x01, //!< General No Ack
HLT = 0x02, //!< Bus Halt
BON = 0x03, //!< Bus ON
TOF = 0x04, //!< Track OFF
TON = 0x05, //!< Track ON
ESTOP = 0x06, //!< Emergency Stop
ARST = 0x07, //!< System Reset
RTOF = 0x08, //!< Request Track OFF
RTON = 0x09, //!< Request Track ON
RESTP = 0x0A, //!< Request Emergency Stop ALL
RSTAT = 0x0C, //!< Request Command Station Status
QNN = 0x0D, //!< Query node number
RQNP = 0x10, //!< Request node parameters
RQMN = 0x11, //!< Request module name
// 20–3F - 1 data byte packets:
KLOC = 0x21, //!< Release Engine
QLOC = 0x22, //!< Query engine
DKEEP = 0x23, //!< Session keep alive
DBG1 = 0x30, //!< Debug with one data byte
EXTC = 0x3F, //!< Extended op-code with no additional bytes
// 40–5F - 2 data byte packets:
RLOC = 0x40, //!< Request engine session
QCON = 0x41, //!< Query Consist
SNN = 0x42, //!< Set Node Number
ALOC = 0x43, //!< Allocate loco to activity
STMOD = 0x44, //!< Set CAB session mode
PCON = 0x45, //!< Consist Engine
KCON = 0x46, //!< Remove Engine from consist
DSPD = 0x47, //!< Set Engine Speed/Dir
DFLG = 0x48, //!< Set Engine Flags
DFNON = 0x49, //!< Set Engine function on
DFNOF = 0x4A, //!< Set Engine function off
SSTAT = 0x4C, //!< Service mode status
NNRSM = 0x4F, //!< Reset to manufacturers defaults
RQNN = 0x50, //!< Request node number
NNREL = 0x51, //!< Node number release
NNACK = 0x52, //!< Node number acknowledge
NNLRN = 0x53, //!< Set node into learn mode
NNULN = 0x54, //!< Release node from learn mode
NNCLR = 0x55, //!< Clear all events from a node
NNEVN = 0x56, //!< Read number of events available in a node
NERD = 0x57, //!< Read back all stored events in a node
RQEVN = 0x58, //!< Request to read number of stored events
WRACK = 0x59, //!< Write acknowledge
RQDAT = 0x5A, //!< Request node data event
RQDDS = 0x5B, //!< Request device data – short mode
BOOTM = 0x5C, //!< Put node into bootload mode
ENUM = 0x5D, //!< Force a self enumeration cycle for use with CAN
NNRST = 0x5E, //!< Restart node
EXTC1 = 0x5F, //!< Extended op-code with 1 additional byte
// 60-7F - 3 data byte packets:
DFUN = 0x60, //!< Set Engine functions
GLOC = 0x61, //!< Get engine session
ERR = 0x63, //!< Command Station Error report
CMDERR = 0x6F, //!< Error messages from nodes during configuration
EVNLF = 0x70, //!< Event space left reply from node
NVRD = 0x71, //!< Request read of a node variable
NENRD = 0x72, //!< Request read of stored events by event index
RQNPN = 0x73, //!< Request read of a node parameter by index
NUMEV = 0x74, //!< Number of events stored in node
CANID = 0x75, //!< Set a CAN_ID in existing FLiM node
EXTC2 = 0x7F, //!< Extended op-code with 2 additional bytes
// 80-9F - 4 data byte packets:
RDCC3 = 0x80, //!< Request 3-byte DCC Packet
WCVO = 0x82, //!< Write CV (byte) in OPS mode
WCVB = 0x83, //!< Write CV (bit) in OPS mode
QCVS = 0x84, //!< Read CV
PCVS = 0x85, //!< Report CV
ACON = 0x90, //!< Accessory ON
ACOF = 0x91, //!< Accessory OFF
AREQ = 0x92, //!< Accessory Request Event
ARON = 0x93, //!< Accessory Response Event
AROF = 0x94, //!< Accessory Response Event
EVULN = 0x95, //!< Unlearn an event in learn mode
NVSET = 0x96, //!< Set a node variable
NVANS = 0x97, //!< Response to a request for a node variable value
ASON = 0x98, //!< Accessory Short ON
ASOF = 0x99, //!< Accessory Short OFF
ASRQ = 0x9A, //!< Accessory Short Request Event
PARAN = 0x9B, //!< Response to request for individual node parameter
REVAL = 0x9C, //!< Request for read of an event variable
ARSON = 0x9D, //!< Accessory Short Response Event
ARSOF = 0x9E, //!< Accessory Short Response Event
EXTC3 = 0x9F, //!< Extended op-code with 3 additional bytes
// A0-BF - 5 data byte packets:
RDCC4 = 0xA0, //!< Request 4-byte DCC Packet
WCVS = 0xA2, //!< Write CV in Service mode
ACON1 = 0xB0, //!< Accessory ON
ACOF1 = 0xB1, //!< Accessory OFF
REQEV = 0xB2, //!< Read event variable in learn mode
ARON1 = 0xB3, //!< Accessory Response Event
AROF1 = 0xB4, //!< Accessory Response Event
NEVAL = 0xB5, //!< Response to request for read of EV value
PNN = 0xB6, //!< Response to Query Node
ASON1 = 0xB8, //!< Accessory Short ON
ASOF1 = 0xB9, //!< Accessory Short OFF
ARSON1 = 0xBD, //!< Accessory Short Response Event with one data byte
ARSOF1 = 0xBE, //!< Accessory Short Response Event with one data byte
EXTC4 = 0xBF, //!< Extended op-code with 4 data bytes
// C0-DF - 6 data byte packets:
RDCC5 = 0xC0, //!< Request 5-byte DCC Packet
WCVOA = 0xC1, //!< Write CV (byte) in OPS mode by address
CABDAT = 0xC2, //!< Cab Data
FCLK = 0xCF, //!< Fast Clock
// E0-FF - 7 data byte packets:
RDCC6 = 0xE0, //!< Request 6-byte DCC Packet
PLOC = 0xE1, //!< Engine report
NAME = 0xE2, //!< Response to request for node name string
STAT = 0xE3, //!< Command Station status report
PARAMS = 0xEF, //!< Response to request for node parameters
ACON3 = 0xF0, //!< Accessory ON
ACOF3 = 0xF1, //!< Accessory OFF
ENRSP = 0xF2, //!< Response to request to read node events
ARON3 = 0xF3, //!< Accessory Response Event
AROF3 = 0xF4, //!< Accessory Response Event
EVLRNI = 0xF5, //!< Teach an event in learn mode using event indexing
ACDAT = 0xF6, //!< Accessory node data event
ARDAT = 0xF7, //!< Accessory node data Response
ASON3 = 0xF8, //!< Accessory Short ON
ASOF3 = 0xF9, //!< Accessory Short OFF
DDES = 0xFA, //!< Device data event (short mode)
DDRS = 0xFB, //!< Device data response (short mode)
ARSON3 = 0xFD, //!< Accessory Short Response Event
ARSOF3 = 0xFE, //!< Accessory Short Response Event
EXTC6 = 0xFF, //!< Extended op-code with 6 data bytes
};
}
#endif

Datei anzeigen

@ -0,0 +1,176 @@
/**
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* Copyright (C) 2026 Reinder Feenstra
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_CBUS_CBUSTOSTRING_HPP
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_CBUS_CBUSTOSTRING_HPP
#include <string_view>
#include "cbusopcode.hpp"
namespace CBUS {
constexpr std::string_view toString(OpCode opCode)
{
switch(opCode)
{
using enum OpCode;
// 00-1F – 0 data bytes packets:
case ACK: return "ACK";
case NAK: return "NAK";
case HLT: return "HLT";
case BON: return "BON";
case TOF: return "TOF";
case TON: return "TON";
case ESTOP: return "ESTOP";
case ARST: return "ARST";
case RTOF: return "RTOF";
case RTON: return "RTON";
case RESTP: return "RESTP";
case RSTAT: return "RSTAT";
case QNN: return "QNN";
case RQNP: return "RQNP";
case RQMN: return "RQMN";
// 20–3F - 1 data byte packets:
case KLOC: return "KLOC";
case QLOC: return "QLOC";
case DKEEP: return "DKEEP";
case DBG1: return "DBG1";
case EXTC: return "EXTC";
// 40–5F - 2 data byte packets:
case RLOC: return "RLOC";
case QCON: return "QCON";
case SNN: return "SNN";
case ALOC: return "ALOC";
case STMOD: return "STMOD";
case PCON: return "PCON";
case KCON: return "KCON";
case DSPD: return "DSPD";
case DFLG: return "DFLG";
case DFNON: return "DFNON";
case DFNOF: return "DFNOF";
case SSTAT: return "SSTAT";
case NNRSM: return "NNRSM";
case RQNN: return "RQNN";
case NNREL: return "NNREL";
case NNACK: return "NNACK";
case NNLRN: return "NNLRN";
case NNULN: return "NNULN";
case NNCLR: return "NNCLR";
case NNEVN: return "NNEVN";
case NERD: return "NERD";
case RQEVN: return "RQEVN";
case WRACK: return "WRACK";
case RQDAT: return "RQDAT";
case RQDDS: return "RQDDS";
case BOOTM: return "BOOTM";
case ENUM: return "ENUM";
case NNRST: return "NNRST";
case EXTC1: return "EXTC1";
// 60-7F - 3 data byte packets:
case DFUN: return "DFUN";
case GLOC: return "GLOC";
case ERR: return "ERR";
case CMDERR: return "CMDERR";
case EVNLF: return "EVNLF";
case NVRD: return "NVRD";
case NENRD: return "NENRD";
case RQNPN: return "RQNPN";
case NUMEV: return "NUMEV";
case CANID: return "CANID";
case EXTC2: return "EXTC2";
// 80-9F - 4 data byte packets:
case RDCC3: return "RDCC3";
case WCVO: return "WCVO";
case WCVB: return "WCVB";
case QCVS: return "QCVS";
case PCVS: return "PCVS";
case ACON: return "ACON";
case ACOF: return "ACOF";
case AREQ: return "AREQ";
case ARON: return "ARON";
case AROF: return "AROF";
case EVULN: return "EVULN";
case NVSET: return "NVSET";
case NVANS: return "NVANS";
case ASON: return "ASON";
case ASOF: return "ASOF";
case ASRQ: return "ASRQ";
case PARAN: return "PARAN";
case REVAL: return "REVAL";
case ARSON: return "ARSON";
case ARSOF: return "ARSOF";
case EXTC3: return "EXTC3";
// A0-BF - 5 data byte packets:
case RDCC4: return "RDCC4";
case WCVS: return "WCVS";
case ACON1: return "ACON1";
case ACOF1: return "ACOF1";
case REQEV: return "REQEV";
case ARON1: return "ARON1";
case AROF1: return "AROF1";
case NEVAL: return "NEVAL";
case PNN: return "PNN";
case ASON1: return "ASON1";
case ASOF1: return "ASOF1";
case ARSON1: return "ARSON1";
case ARSOF1: return "ARSOF1";
case EXTC4: return "EXTC4";
// C0-DF - 6 data byte packets:
case RDCC5: return "RDCC5";
case WCVOA: return "WCVOA";
case CABDAT: return "CABDAT";
case FCLK: return "FCLK";
// E0-FF - 7 data byte packets:
case RDCC6: return "RDCC6";
case PLOC: return "PLOC";
case NAME: return "NAME";
case STAT: return "STAT";
case PARAMS: return "PARAMS";
case ACON3: return "ACON3";
case ACOF3: return "ACOF3";
case ENRSP: return "ENRSP";
case ARON3: return "ARON3";
case AROF3: return "AROF3";
case EVLRNI: return "EVLRNI";
case ACDAT: return "ACDAT";
case ARDAT: return "ARDAT";
case ASON3: return "ASON3";
case ASOF3: return "ASOF3";
case DDES: return "DDES";
case DDRS: return "DDRS";
case ARSON3: return "ARSON3";
case ARSOF3: return "ARSOF3";
case EXTC6: return "EXTC6";
}
return {};
}
}
#endif