#ifndef LINUXCNC_WEB_WASM_SIM_DEVICE_IO_H #define LINUXCNC_WEB_WASM_SIM_DEVICE_IO_H #include #ifdef __cplusplus extern "C" { #endif #define SIM_DEVICE_MAX_ENCODERS 8U #define SIM_DEVICE_MAX_ACKS 64U enum sim_device_result { SIM_DEVICE_OK = 0, SIM_DEVICE_ERR_ARGUMENT = -1000, SIM_DEVICE_ERR_RANGE = -1001, SIM_DEVICE_ERR_NONFINITE = -1002, SIM_DEVICE_ERR_CAPACITY = -1003, SIM_DEVICE_ERR_STATE = -1004, SIM_DEVICE_ERR_INTERLOCK = -1005, SIM_DEVICE_ERR_DUPLICATE = -1006, SIM_DEVICE_ERR_MISSING = -1007, SIM_DEVICE_ERR_LATE_ACK = -1008, SIM_DEVICE_ERR_TIMEOUT = -1009, }; enum sim_device_ack_status { SIM_DEVICE_ACK_UNUSED = 0, SIM_DEVICE_ACK_PENDING = 1, SIM_DEVICE_ACK_ACKED = 2, SIM_DEVICE_ACK_TIMED_OUT = 3, SIM_DEVICE_ACK_ABORTED = 4, }; typedef struct sim_device_encoder_state { uint32_t registered; double speed_rps; uint32_t ppr; double scale; int32_t raw_count; int32_t count; double position; double velocity; uint32_t phase_a; uint32_t phase_b; uint32_t phase_z; uint32_t index_enable; uint32_t index_pulse; uint32_t tick; } sim_device_encoder_state; typedef struct sim_device_coolant_state { uint32_t mist_requested; uint32_t flood_requested; uint32_t lube_requested; uint32_t mist; uint32_t flood; uint32_t lube; uint32_t fault; } sim_device_coolant_state; typedef struct sim_device_safety_state { uint32_t door_open; uint32_t input_ok; uint32_t estop; uint32_t fault; uint32_t interlock_ok; uint32_t latched_fault; uint32_t recovery_epoch; } sim_device_safety_state; typedef struct sim_device_ack_entry { uint32_t used; uint32_t operation_id; uint32_t issued_tick; uint32_t deadline_tick; uint32_t status; } sim_device_ack_entry; typedef struct sim_device_io_state { uint32_t tick; uint32_t encoder_count; sim_device_encoder_state encoders[SIM_DEVICE_MAX_ENCODERS]; sim_device_coolant_state coolant; sim_device_safety_state safety; sim_device_ack_entry acks[SIM_DEVICE_MAX_ACKS]; int32_t last_error; } sim_device_io_state; typedef struct sim_device_io { sim_device_io_state state; double cycle_time; double phase_accumulator[SIM_DEVICE_MAX_ENCODERS]; } sim_device_io; int sim_device_init(sim_device_io *device, uint32_t encoder_count, double cycle_time); int sim_device_reset(sim_device_io *device); int sim_device_encoder_set_speed(sim_device_io *device, uint32_t channel, double speed_rps); int sim_device_encoder_set_config(sim_device_io *device, uint32_t channel, uint32_t ppr, double scale); int sim_device_encoder_set_index_enable(sim_device_io *device, uint32_t channel, uint32_t enable); int sim_device_coolant_command(sim_device_io *device, uint32_t mist, uint32_t flood, uint32_t lube); int sim_device_coolant_set_fault(sim_device_io *device, uint32_t fault); int sim_device_door_set(sim_device_io *device, uint32_t open); int sim_device_interlock_set(sim_device_io *device, uint32_t input_ok); int sim_device_interlock_reset(sim_device_io *device); int sim_device_estop_set(sim_device_io *device, uint32_t estop); int sim_device_step(sim_device_io *device, uint32_t ticks); int sim_device_ack_issue(sim_device_io *device, uint32_t operation_id, uint32_t timeout_ticks); int sim_device_ack_ack(sim_device_io *device, uint32_t operation_id); int sim_device_ack_abort(sim_device_io *device, uint32_t operation_id); int sim_device_ack_step(sim_device_io *device, uint32_t ticks); int sim_device_read_state(const sim_device_io *device, sim_device_io_state *state); uint64_t sim_device_state_hash(const sim_device_io *device); uint32_t sim_device_canonical(const sim_device_io *device, char *output, uint32_t capacity); #ifdef __cplusplus } #endif #endif