
#ifndef ETHERCAT_DATA_STRUCTURES_H
#define ETHERCAT_DATA_STRUCTURES_H

#pragma once

#include "../ethercat_types.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define EC_MAXNAME  40

#define ECT_MBXPROT_AOE  0x0001
#define ECT_MBXPROT_EOE  0x0002
#define ECT_MBXPROT_COE  0x0004
#define ECT_MBXPROT_FOE  0x0008
#define ECT_MBXPROT_SOE  0x0010
#define ECT_MBXPROT_VOE  0x0020

#define ECT_COEDET_SDO         0x01
#define ECT_COEDET_SDOINFO     0x02
#define ECT_COEDET_PDOASSIGN   0x04
#define ECT_COEDET_PDOCONFIG   0x08
#define ECT_COEDET_UPLOAD      0x10
#define ECT_COEDET_SDOCA       0x20

#pragma pack(push, 1)
typedef struct {
    uint16_t StartAddr;
    uint16_t SMlength;
    uint32_t SMflags;
} ec_smt;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct {
    uint32_t LogStart;
    uint16_t LogLength;
    uint8_t  LogStartbit;
    uint8_t  LogEndbit;
    uint16_t PhysStart;
    uint8_t  PhysStartBit;
    uint8_t  FMMUtype;
    uint8_t  FMMUactive;
    uint8_t  unused1;
    uint16_t unused2;
} ec_fmmut;
#pragma pack(pop)

typedef struct {
    uint16_t bits;
    uint32_t bytes;
    void*    ptr;
    uint32_t offset;
    uint8_t  startbit;
} slave_io_desc_blittable_t;

typedef struct {
    uint8_t  capable;
    void*    connection;
    void*    sm_context;
    uint16_t connection_id;
    uint16_t safety_address;
    uint16_t safe_input_size;
    uint16_t safe_output_size;
    uint32_t pdo_input_offset;
    uint32_t pdo_output_offset;
} slave_fsoe_blittable_t;

typedef struct {
    uint16_t length;
    uint16_t write_offset;
    uint16_t read_length;
    uint16_t read_offset;
    uint16_t supported_proto;
    uint8_t  cnt;
} slave_mailbox_blittable_t;

typedef struct {
    uint16_t reserved_sii;
    uint8_t  read_8byte;
    uint8_t  pdi;
} slave_eeprom_config_blittable_t;

typedef struct {
    int32_t  state;
    int32_t  rmp_state;
    uint16_t instate_ex;
} slave_handler_blittable_t;

typedef struct {
    uint32_t vendor_id;
    uint32_t product_id;
    uint32_t revision;
    uint32_t serial;
    uint16_t itype;
    uint16_t dtype;
} slave_identity_blittable_t;

typedef struct {
    slave_identity_blittable_t identity;
    char     group_name[EC_MAXNAME + 1];
    char     device_name[EC_MAXNAME + 1];
    uint16_t sm_count;
} slave_metadata_blittable_t;

typedef struct {
    uint8_t  is_optional;
    uint8_t  supports_frame_repeat;
    uint8_t  mailbox_side;
    uint8_t  coe_details;
    uint8_t  foe_details;
    uint8_t  eoe_details;
    uint8_t  soe_details;
} slave_capabilities_blittable_t;

typedef struct {
    uint8_t  assignment_enabled;
    uint8_t  configuration_enabled;
    uint8_t  config_initialized;
    uint8_t  supports_complete_access;
} slave_pdo_config_blittable_t;

typedef struct {
    int16_t  ebus_current;
    uint8_t  block_lrw;
    uint8_t  group;
    uint8_t  is_lost;
} slave_runtime_blittable_t;

typedef struct {
    uint8_t  sm_type[8];
    uint16_t sm_app_length[8];
    uint8_t  fmmu_func[4];
    uint8_t  fmmu_unused;
} slave_sm_fmmu_blittable_t;

typedef struct {
    void*    in;
    uint8_t  in_full;
    int32_t  overrun;
} slave_proto_mbx_blittable_t;

typedef struct {
    uint8_t  has_dc;
    uint8_t  phy_type;
    uint8_t  link_count;
    uint8_t  active_ports;
    uint8_t  consumed_ports;
    uint16_t parent;
    uint8_t  parent_port;
    uint8_t  entry_port;
} slave_topology_blittable_t;

typedef struct {
    int32_t  recvtime[4];
    int32_t  propagation_delay;
    uint16_t next;
    uint16_t prev;
    int32_t  cycle0;
    int32_t  cycle1;
    int32_t  shift;
    uint16_t active;
} slave_dc_blittable_t;

typedef struct {

    uint16_t state;
    uint16_t ALstatuscode;
    uint16_t configadr;
    uint16_t aliasadr;

    slave_fsoe_blittable_t fsoe;

    slave_io_desc_blittable_t output;
    slave_io_desc_blittable_t input;

    uint8_t  SM_buffer[64];

    uint8_t  FMMU_buffer[64];

    slave_sm_fmmu_blittable_t sm_fmmu;

    slave_mailbox_blittable_t mbx;

    slave_topology_blittable_t topo;

    slave_dc_blittable_t dc;

    slave_eeprom_config_blittable_t eeprom_config;

    slave_runtime_blittable_t runtime;

    void*    PO2SOconfig;

    slave_handler_blittable_t handler;

    slave_proto_mbx_blittable_t coe;
    slave_proto_mbx_blittable_t soe;
    slave_proto_mbx_blittable_t foe;
    slave_proto_mbx_blittable_t eoe;
    slave_proto_mbx_blittable_t voe;
    slave_proto_mbx_blittable_t aoe;

    void*    mbxstatus;

    slave_metadata_blittable_t metadata;

    slave_pdo_config_blittable_t pdo_config;

    slave_capabilities_blittable_t capabilities;

} ec_slavet;

#pragma pack(push, 1)
typedef struct {
    uint8_t  group_idx;
    uint8_t  image_idx;
    uint8_t  order_idx;
    uint8_t  name_idx;
    uint8_t  coe_details;
    uint8_t  foe_details;
    uint8_t  eoe_details;
    uint8_t  soe_details;
    uint8_t  flags;
    int16_t  ebus_current_ma;
    uint16_t physical_port;
    uint8_t  reserved[8];
} ec_sii_general_info_t;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct {
    uint32_t ReadCount;
    uint32_t WriteCount;
    uint32_t ErrorCount;
    uint32_t TotalBytesRead;
    uint32_t TotalBytesWritten;
    uint64_t LastCycleTimeNs;
    uint64_t MinCycleTimeNs;
    uint64_t MaxCycleTimeNs;
    uint64_t AvgCycleTimeNs;
} ec_pdo_stats_t;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct {
    uint16_t Index;
    uint8_t  SubIndex;
    uint8_t  BitLength;
    uint16_t BitOffset;
    uint8_t  Name[64];
    uint8_t  Unit[16];
    uint8_t  Readable;
    uint8_t  Writable;
} ec_pdo_mapping_entry_t;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct {
    uint8_t  name[128];
    uint8_t  desc[128];
    int16_t  slaveNum;
    int16_t  redundantSlaveNum;
} ec_network_info_t;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct {
    uint32_t vendor_id;
    uint32_t product_code;
    uint32_t revision_number;
    uint32_t serial_number;
    char     device_name[64];
    char     vendor_name[64];
    uint16_t sync_manager_count;
    uint16_t fmmu_count;
    uint8_t  supports_coe;
    uint8_t  supports_foe;
    uint8_t  supports_eoe;
    uint8_t  supports_soe;
} ec_slave_info_t;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct {
    double   current_cycle_time_us;
    double   jitter_us;
    uint32_t lost_frames;
    uint32_t corrupted_frames;
    double   bus_utilization;
} ec_realtime_stats_t;
#pragma pack(pop)

typedef struct {

    uint32_t CacheCnt;
    uint32_t RTcnt;
    uint32_t cycle_count;

    uint32_t ErrorCacheCnt;
    uint32_t ErrorCnt;

    uint16_t WKC;
    uint16_t ExpectedWKC;

    uint32_t CycleTimeSpan;

    uint32_t frame_errors;
    uint32_t lost_frames;
    uint32_t checksum_errors;
    uint32_t timeout_frames;

    uint32_t rx_error_count[EC_MAXSLAVE];
    uint32_t tx_error_count[EC_MAXSLAVE];
    uint16_t lost_link_count[EC_MAXSLAVE];
    uint16_t invalid_frame_count[EC_MAXSLAVE];

    uint16_t working_counter_errors;
    uint16_t consecutive_wkc_errors;
    uint32_t total_wkc_mismatches;

    uint64_t cycle_start_time;
    double   cycle_time_accumulator;
    uint64_t last_snapshot_time;
    uint32_t snapshot_cycle_count;

    double   last_cycle_time_us;
    double   jitter_accumulator;
    double   max_jitter_in_second;
    uint32_t jitter_sample_count;

} ec_internal_diagnostics_t;

#ifdef __cplusplus
}
#endif

#endif
