
#ifndef ETHERCAT_SLAVE_DC_H
#define ETHERCAT_SLAVE_DC_H

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

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    DC_FREE_RUN     = 0,
    DC_SM_SYNCHRON  = 1,
    DC_SYNCHRON     = 2,
    DC_SYNCHRON_01  = 3
} dc_sync_mode_t;

#ifndef DYNAMIC_LOAD

void     SetMasterDCCycleTime(uint16_t master_index, uint32_t time_ns);
void     SetMasterLoopCycleTime(uint16_t master_index, uint32_t time_ns);
void     SetSyncBySlaveIndex(uint16_t master_index, uint16_t slave_index,
                              uint32_t sync0_ns, uint32_t sync1_ns, int32_t shift_ns);
int      ConfigureDCAll(uint16_t master_index, uint32_t sync0_ns, uint32_t sync1_ns);
int      UpdatePropagationDelays(uint16_t master_index);
int      AutoCalculateDCShift(uint16_t master_index);
void     EnableContinuousMeasurement(uint16_t master_index, BOOL enable, uint32_t interval_sec);
void     EnableDriftCompensation(uint16_t master_index, BOOL enable, int32_t threshold_ns, int32_t gain);
void     SetDCAutoShiftEnabled(uint16_t master_index, BOOL enable);
BOOL     GetDCAutoShiftEnabled(uint16_t master_index);
int32_t  GetSlavePropagationDelay(uint16_t master_index, uint16_t slave_index);
int32_t  GetMaxPropagationDelay(uint16_t master_index);

BOOL     SetDcSyncMode(uint16_t master_index, uint16_t slave_index, uint8_t sync_type);
uint8_t  GetDcSyncMode(uint16_t master_index, uint16_t slave_index);

BOOL     GetSlaveSyncWindowStatus(uint16_t master_index, uint16_t slave_index,
                                   int* diff_ns, int* max_diff_ns, int* min_diff_ns,
                                   BOOL* in_sync, uint32_t* out_of_sync_count);
void     SetSyncWindowThreshold(uint16_t master_index, int threshold_ns);
int      GetSyncWindowThreshold(uint16_t master_index);
void     ResetSlaveSyncWindowStats(uint16_t master_index, uint16_t slave_index);
int      GetMaxSyncDifference(uint16_t master_index);
BOOL     IsAllSlavesInSync(uint16_t master_index);

#endif

struct dll;

BOOL     dc_configure_with_mode(const struct dll* dll,
                                       uint16_t master_index, uint16_t slave_index,
                                       dc_sync_mode_t mode,
                                       uint32_t sync0_ns, uint32_t sync1_ns,
                                       int32_t shift_ns);

BOOL     slave_has_dc(const struct dll* dll, uint16_t master_index, uint16_t slave_index);

BOOL     slave_has_esi_dc_sync(const struct dll* dll,
                                      uint16_t master_index, uint16_t slave_index);

BOOL     slave_has_esi_dc_sync_from_xml(const struct dll* dll,
                                               uint16_t master_index, uint16_t slave_index,
                                               const char* esi_xml_path);

int64_t  get_master_dc_time(const struct dll* dll, uint16_t master_index);

uint16_t get_reference_clock_slave(const struct dll* dll, uint16_t master_index);

#ifdef __cplusplus
}
#endif

#endif
