98 REQ_EMERGENCY_STOP = 0x02,
100 REQ_QUERY_SPEED = 0x10,
103 REQ_CONTROLLER_CONFIG = 0x20,
104 REQ_CONSIST_CONFIG = 0x30,
105 REQ_TRACTION_MGMT = 0x40,
114 CTRLREQ_ASSIGN_CONTROLLER = 0x01,
115 CTRLREQ_RELEASE_CONTROLLER = 0x02,
116 CTRLREQ_QUERY_CONTROLLER = 0x03,
117 CTRLREQ_NOTIFY_CONTROLLER_CHANGED = 0x04,
120 CNSTREQ_ATTACH_NODE = 0x01,
121 CNSTREQ_DETACH_NODE = 0x02,
122 CNSTREQ_QUERY_NODES = 0x03,
125 MGMTREQ_RESERVE = 0x01,
126 MGMTREQ_RELEASE = 0x02,
129 RESP_QUERY_SPEED = REQ_QUERY_SPEED,
130 RESP_QUERY_FN = REQ_QUERY_FN,
131 RESP_CONTROLLER_CONFIG = REQ_CONTROLLER_CONFIG,
132 RESP_CONSIST_CONFIG = REQ_CONSIST_CONFIG,
133 RESP_TRACTION_MGMT = REQ_TRACTION_MGMT,
136 SPEEDRESP_STATUS_IS_ESTOP = 1,
139 CTRLRESP_ASSIGN_CONTROLLER = CTRLREQ_ASSIGN_CONTROLLER,
140 CTRLRESP_QUERY_CONTROLLER = CTRLREQ_QUERY_CONTROLLER,
141 CTRLRESP_NOTIFY_CONTROLLER_CHANGED = CTRLREQ_NOTIFY_CONTROLLER_CHANGED,
144 CTRLRESP_ASSIGN_ERROR_TRAIN = 0x02,
145 CTRLRESP_ASSIGN_ERROR_CONTROLLER = 0x01,
148 CNSTRESP_ATTACH_NODE = CNSTREQ_ATTACH_NODE,
149 CNSTRESP_DETACH_NODE = CNSTREQ_DETACH_NODE,
150 CNSTRESP_QUERY_NODES = CNSTREQ_QUERY_NODES,
152 CNSTFLAGS_ALIASVALID = 0x01,
153 CNSTFLAGS_REVERSE = 0x02,
154 CNSTFLAGS_LINKF0 = 0x04,
155 CNSTFLAGS_LINKFN = 0x08,
156 CNSTFLAGS_HIDE = 0x80,
159 MGMTRESP_RESERVE = MGMTREQ_RESERVE,
160 MGMTRESP_HEARTBEAT = 0x03,
162 PROXYREQ_ALLOCATE = 0x01,
163 PROXYREQ_ATTACH = 0x02,
164 PROXYREQ_DETACH = 0x03,
165 PROXYREQ_MANAGE = 0x80,
167 PROXYRESP_ALLOCATE = PROXYREQ_ALLOCATE,
168 PROXYRESP_ATTACH = PROXYREQ_ATTACH,
169 PROXYRESP_MANAGE = PROXYREQ_MANAGE,
172 PROXYREQ_MANAGE_RESERVE = 0x01,
173 PROXYREQ_MANAGE_RELEASE = 0x02,
175 PROXYRESP_MANAGE_RESERVE_REPLY = 0x01,
180 PROXYTYPE_MARKLIN_DIGITAL = 3,
181 PROXYTYPE_MARKLIN_DELTA = 4,
182 PROXYTYPE_MARKLIN_MFX = 5,
183 PROXYTYPE_SELECTRIX = 6,
184 PROXYTYPE_MTH_DCS = 7,
185 PROXYTYPE_LIONEL_TMCC = 8,
220 case dcc::TrainAddressType::DCC_SHORT_ADDRESS:
222 case dcc::TrainAddressType::DCC_LONG_ADDRESS:
224 case dcc::TrainAddressType::MM:
227 DIE(
"Unknown train address type");
248 *addr = (
id & 0x3FFF);
253 *type = dcc::TrainAddressType::DCC_LONG_ADDRESS;
257 *type = dcc::TrainAddressType::DCC_SHORT_ADDRESS;
263 *type = dcc::TrainAddressType::MM;
264 *addr = (
id & 0x3FFF);
282 if ((type == dcc::TrainAddressType::DCC_LONG_ADDRESS) && (addr < 128))
287 char *e = integer_to_buffer(addr, s);
288 ret.resize(e - &ret[0]);
289 if (type == dcc::TrainAddressType::MM)
295 if (type == dcc::TrainAddressType::DCC_SHORT_ADDRESS)
316 uint32_t decoded_address = 0xFFFF;
318 node_id, &decoded_type, &decoded_address))
329 return mac_to_string(idbuf);
333 static Payload estop_set_payload() {
335 p[0] = REQ_EMERGENCY_STOP;
339 static Payload speed_set_payload(Velocity v) {
341 p[0] = REQ_SET_SPEED;
346 static Payload speed_get_payload() {
348 p[0] = REQ_QUERY_SPEED;
367 if (std::isnan(v->
speed()))
377 *is_estop = (p[3] & SPEEDRESP_STATUS_IS_ESTOP) != 0;
382 static Payload fn_set_payload(
unsigned address, uint16_t value) {
385 p[1] = (address >> 16) & 0xff;
386 p[2] = (address >> 8) & 0xff;
387 p[3] = address & 0xff;
388 p[4] = (value >> 8) & 0xff;
393 static Payload fn_get_payload(
unsigned address) {
396 p[1] = (address >> 16) & 0xff;
397 p[2] = (address >> 8) & 0xff;
398 p[3] = address & 0xff;
408 const Payload &p, uint16_t *value,
unsigned *address)
414 unsigned num = uint8_t(p[1]);
416 num |= uint8_t(p[2]);
418 num |= uint8_t(p[3]);
420 *value = (((uint16_t)p[4]) << 8) | uint8_t(p[5]);
424 static Payload assign_controller_payload(
Node *ctrl)
427 p[0] = REQ_CONTROLLER_CONFIG;
428 p[1] = CTRLREQ_ASSIGN_CONTROLLER;
434 static Payload release_controller_payload(
Node *ctrl)
437 p[0] = REQ_CONTROLLER_CONFIG;
438 p[1] = CTRLREQ_RELEASE_CONTROLLER;
444 static Payload consist_add_payload(
NodeID slave, uint8_t flags)
447 p[0] = REQ_CONSIST_CONFIG;
448 p[1] = CNSTREQ_ATTACH_NODE;
454 static Payload consist_add_response(
NodeID slave, uint16_t error_code)
457 p[0] = RESP_CONSIST_CONFIG;
458 p[1] = CNSTRESP_ATTACH_NODE;
467 p[0] = REQ_CONSIST_CONFIG;
468 p[1] = CNSTREQ_DETACH_NODE;
473 static Payload consist_del_response(
NodeID slave, uint16_t error_code)
475 Payload p = consist_add_response(slave, error_code);
476 p[1] = CNSTRESP_DETACH_NODE;
480 static Payload consist_qry_payload()
483 p[0] = REQ_CONSIST_CONFIG;
484 p[1] = CNSTREQ_QUERY_NODES;
488 static Payload consist_qry_payload(uint8_t arg)
491 p[0] = REQ_CONSIST_CONFIG;
492 p[1] = CNSTREQ_QUERY_NODES;
497 static Payload consist_qry_response_short(uint8_t num_entries)
500 p[0] = RESP_CONSIST_CONFIG;
501 p[1] = CNSTRESP_QUERY_NODES;
506 static Payload consist_qry_response_long(
507 uint8_t num_entries, uint8_t index, uint8_t flags,
NodeID slave)
510 p[0] = RESP_CONSIST_CONFIG;
511 p[1] = CNSTRESP_QUERY_NODES;
524 p[0] = RESP_TRACTION_MGMT;
525 p[1] = MGMTRESP_HEARTBEAT;
534 p[0] = REQ_TRACTION_MGMT;