Topic: tech dcc pc src prev next
tech dcc pc src > packet.h
#ifndef HERMES_PACKET_H
#define HERMES_PACKET_H
#include <stdbool.h>
#include "cfg.h"
#define PACKET_PROGRAMMING_PREAMBLE_LENGTH 20
#define PACKET_NORMAL_PREAMBLE_LENGTH 16
// Maximum data length (including ECC).
#define PACKET_MAX_LENGTH 6
// Maximum data length (including ECC, not including preamble) in bits.
#define PACKET_MAX_DATA_LENGTH_BITS (PACKET_MAX_LENGTH * 9 + 1)
// Maximum packet bit length (including ECC and preamble).
#define PACKET_MAX_RAW_LENGTH_BITS (PACKET_PROGRAMMING_PREAMBLE_LENGTH + PACKET_MAX_DATA_LENGTH_BITS)
typedef struct
{
// Packet bytes in transmission order (MSB first), including the ECC byte.
unsigned char data[PACKET_MAX_LENGTH];
// This packet should be transmitted as a service mode packet.
// Programming packets have an extended preamble.
bool service_mode;
// Packet length in bytes, including the ECC byte.
unsigned char length;
} packet;
packet Packet_CreateEmpty();
packet Packet_CreateReset();
packet Packet_CreatePagePreset();
packet Packet_CreateIdle();
packet Packet_CreateSpeed128(
cfg_address_type address,
bool forward,
unsigned char speed
);
packet Packet_CreateSpeed28(
cfg_address_type address,
bool forward,
unsigned char speed
);
packet Packet_CreatePomAccWrite(
cfg_address_type target_address,
cfg_address_type cv_no,
unsigned char cv_data
);
packet Packet_CreatePomLocoWrite(
cfg_address_type target_address,
cfg_address_type cv_no,
unsigned char cv_data
);
packet Packet_CreateAccessoryBasic(
cfg_address_type address,
unsigned char output,
bool state
);
packet Packet_Create2(unsigned char byte1, unsigned char byte2);
packet Packet_Create3(unsigned char byte1, unsigned char byte2, unsigned char byte3);
packet Packet_Create4(
unsigned char byte1,
unsigned char byte2,
unsigned char byte3,
unsigned char byte4
);
packet Packet_Create5(
unsigned char byte1,
unsigned char byte2,
unsigned char byte3,
unsigned char byte4,
unsigned char byte5
);
packet Packet_CreateServiceMode2(unsigned char byte1, unsigned char byte2);
packet Packet_CreateServiceMode3(unsigned char byte1, unsigned char byte2, unsigned char byte3);
// Append a byte to an existing packet. Returns true if the byte was appended,
// false if the packet is already at the maximum size.
bool Packet_AppendByte(packet *p, unsigned char b);
// Check whether a packet's ECC byte is valid.
bool Packet_EccValid(const packet *p);
// Get the raw length of a packet in bits.
unsigned char Packet_RawLength(const packet *p);
// Copy the raw packet data to a char array.
void Packet_RawData(unsigned char *out, const packet *p);
// Check whether packets 'a' and 'b' match. Only bits set in 'mask' are
// checked. The checksum (final byte) is ignored.
bool Packet_Matches(const packet *a, const packet *b, const packet *mask);
// Check wheter this is a reset packet.
bool Packet_IsReset(const packet *p);
// Check whether this is a service mode packet by looking at the first
// (address) byte. If a packet is a valid service mode packet, it could also
// be an operations mode packet; the decoder must make further checks before
// acting on a service mode packet.
bool Packet_IsServiceMode(const packet *p);
// Check whether this is a 28-step speed and direction packet.
bool Packet_Is28Step(const packet *p);
// Get the address from a 28-step speed packet.
cfg_address_type Packet_28StepAddress(const packet *p);
// Get the speed from a 28-step speed packet.
unsigned char Packet_28StepSpeed(const packet *p);
// Get the direction from a 28-step speed packet.
bool Packet_28StepFwd(const packet *p);
// Check whether this is a 128-step speed and direction packet.
bool Packet_Is128Step(const packet *p);
// Get the speed from a 128-step speed packet.
unsigned char Packet_128StepSpeed(const packet *p);
// Get the direction from a 128-step speed packet.
bool Packet_128StepFwd(const packet *p);
// Get the address from an advanced operations mode packet (128 step speed,
// function group, etc.).
cfg_address_type Packet_AdvAddress(const packet *p);
// Check whether the given packet is a direct mode programming packet.
bool Packet_IsDirectProgramming(const packet *p);
// Get the CV number from a direct mode programming packet. The first CV is 1.
unsigned short Packet_DirectCv(const packet *p);
// Get the value from a direct mode programming packet.
unsigned char Packet_DirectValue(const packet *p);
// Check whether the given packet is a physical register programming packet
// (this includes all paged mode programming packets).
bool Packet_IsRegisterProgramming(const packet *p);
// Get the register number from a physical register programming packet.
unsigned char Packet_Register(const packet *p);
// Get the value from a physical register programming packet.
unsigned char Packet_RegisterValue(const packet *p);
// Check whether this packet is a long form progamming on main write packet.
bool Packet_IsLocoPomWrite(const packet *p);
// Check whether this packet is a short form acceleration programming on main
// write packet.
bool Packet_IsPomAccelerationWrite(const packet *p);
// Check whether this packet is a short form deceleration programming on main
// write packet.
bool Packet_IsPomDecelerationWrite(const packet *p);
// Get the CV number from a programming on main packet. The first CV is 1.
unsigned short Packet_LocoPomCv(const packet *p);
// Get the value from a programming on main packet.
unsigned char Packet_LocoPomValue(const packet *p);
// Check whether the packet is a basic accessory packet.
bool Packet_IsBasicAccessory(const packet *p);
// Get the address of the stationary decoder from a basic accessory packet.
cfg_address_type Packet_BasicAccessoryAddress(const packet *p);
// Get the new state of the stationary decoder from a basic accessory packet.
bool Packet_BasicAccessoryState(const packet *p);
// Get the output (0 to 7) enclosed in the packet.
unsigned char Packet_BasicAccessoryOutput(const packet *p);
// Check whether this is any type of mobile decoder function packet.
bool Packet_IsFunction(const packet *p);
/*
* Construct a function state packet. Each type of packet controls 4, 5 or 8
* consecutive functions. In each case, the lower bits of the data byte (or
* the entire data byte for 8-bit function packets) control the function
* states. The least significant bit refers to the first function in the
* group.
*/
packet Packet_CreateFunction0_4(cfg_address_type address, unsigned char data);
packet Packet_CreateFunction5_8(cfg_address_type address, unsigned char data);
packet Packet_CreateFunction9_12(cfg_address_type address, unsigned char data);
packet Packet_CreateFunction13_20(cfg_address_type address, unsigned char data);
packet Packet_CreateFunction21_28(cfg_address_type address, unsigned char data);
// Check whether this is a programming on main write instruction for accessory
// decoders.
bool Packet_IsAccPomWrite(const packet *p);
// Get the decoder address of a programming on main packet for accessory
// decoders.
cfg_address_type Packet_AccPomAddress(const packet *p);
// Get the CV of a programming on main packet for accessory decoders.
cfg_address_type Packet_AccPomCv(const packet *p);
// Get the value of a programming on main packet for accessory decoders.
unsigned char Packet_AccPomValue(const packet *p);
#endif