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