#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <getopt.h>
#include "hal.h"
#include "rtapi.h"
#include "rcs.hh"
#include "emc.hh"
#include "emc_nml.hh"
#include "emcglb.h"
#include "inifile.hh"
#include "initool.hh"
#include "nml_oi.hh"
#include "timer.hh"
#include "rcs_print.hh"
#include "tool_parse.h"
static RCS_CMD_CHANNEL *emcioCommandBuffer = 0;
static RCS_CMD_MSG *emcioCommand = 0;
static RCS_STAT_CHANNEL *emcioStatusBuffer = 0;
static EMC_IO_STAT emcioStatus;
static NML *emcErrorBuffer = 0;
static char *ttcomments[CANON_POCKETS_MAX];
static int random_toolchanger = 0;
static int support_start_change = 0;
static const char *progname;
typedef enum {
V1 = 1,
V2 = 2
} version_t;
static int proto = V2;
enum {
EMC_ABORT_BY_TOOLCHANGER_FAULT = EMC_ABORT_USER + 1
};
static const char *strcs[] = { "invalid","RCS_DONE","RCS_EXEC","RCS_ERROR"};
enum {
TI_PREPARING = 1,
TI_PREPARE_COMPLETE = 2,
TI_CHANGING = 4,
TI_CHANGE_COMPLETE = 8,
TI_TC_FAULT = 16,
TI_TC_ABORT = 32,
TI_EMC_ABORT_SIGNALED = 64,
TI_EMC_ABORT_ACKED = 128,
TI_ESTOP_CHANGED = 256,
TI_LUBELEVEL_CHANGED = 512,
TI_START_CHANGE = 1024,
TI_START_CHANGE_ACKED = 2048
};
typedef enum {
ST_IDLE = 0,
ST_PREPARING = 1,
ST_START_CHANGE = 2, ST_CHANGING = 3,
ST_WAIT_FOR_ABORT_ACK = 4, } iostate_t;
static const char *strstate[] = { "IDLE","PREPARING","START_CHANGE", "CHANGING","WAIT_FOR_ABORT_ACK"};
static int toolchanger_reason;
#define TC_FAULT (*(iocontrol_data->toolchanger_faulted))
#define TC_HARDFAULT (TC_FAULT && (toolchanger_reason <= 0))
#define TC_SOFTFAULT (TC_FAULT && (toolchanger_reason > 0))
struct iocontrol_str {
hal_bit_t *user_enable_out;
hal_bit_t *emc_enable_in;
hal_bit_t *user_request_enable;
hal_bit_t *coolant_mist;
hal_bit_t *coolant_flood;
hal_bit_t *lube;
hal_bit_t *lube_level;
hal_bit_t *tool_prepare;
hal_s32_t *tool_prep_pocket;
hal_s32_t tool_prep_index;
hal_s32_t *tool_prep_number;
hal_s32_t *tool_number;
hal_bit_t *tool_prepared;
hal_bit_t *tool_change;
hal_bit_t *tool_changed;
hal_bit_t *emc_abort;
hal_bit_t *emc_abort_ack;
hal_s32_t *emc_reason;
hal_bit_t *toolchanger_fault;
hal_bit_t *toolchanger_fault_ack;
hal_s32_t *toolchanger_reason;
hal_bit_t *start_change;
hal_bit_t *start_change_ack;
hal_bit_t *toolchanger_faulted;
hal_bit_t *toolchanger_clear_fault;
hal_s32_t *state;
} *iocontrol_data;
static int comp_id;
static int emcIoNmlGet()
{
int retval = 0;
if (emcioCommandBuffer == 0) {
emcioCommandBuffer =
new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "tool", emc_nmlfile);
if (!emcioCommandBuffer->valid()) {
rtapi_print_msg(RTAPI_MSG_ERR,
"emcToolCmd buffer not available\n");
delete emcioCommandBuffer;
emcioCommandBuffer = 0;
retval = -1;
} else {
emcioCommand = emcioCommandBuffer->get_address();
}
}
if (emcioStatusBuffer == 0) {
emcioStatusBuffer =
new RCS_STAT_CHANNEL(emcFormat, "toolSts", "tool",
emc_nmlfile);
if (!emcioStatusBuffer->valid()) {
rtapi_print_msg(RTAPI_MSG_ERR,
"toolSts buffer not available\n");
delete emcioStatusBuffer;
emcioStatusBuffer = 0;
retval = -1;
} else {
emcioStatus.heartbeat = 0;
emcioStatus.command_type = 0;
emcioStatus.echo_serial_number = 0;
emcioStatus.status = RCS_DONE;
emcioStatusBuffer->write(&emcioStatus);
}
}
if (emcErrorBuffer == 0) {
emcErrorBuffer =
new NML(nmlErrorFormat, "emcError", "tool", emc_nmlfile);
if (!emcErrorBuffer->valid()) {
rtapi_print_msg(RTAPI_MSG_ERR,
"emcError buffer not available\n");
delete emcErrorBuffer;
emcErrorBuffer = 0;
retval = -1;
}
}
return retval;
}
static int iniLoad(const char *filename)
{
IniFile inifile;
const char *inistring;
char version[LINELEN], machine[LINELEN];
if (inifile.Open(filename) == false) {
return -1;
}
if (NULL != (inistring = inifile.Find("DEBUG", "EMC"))) {
if (1 != sscanf(inistring, "%i", &emc_debug)) {
emc_debug = 0;
}
} else {
emc_debug = 0;
}
if (emc_debug & EMC_DEBUG_IOCONTROL) {
rtapi_set_msg_level(RTAPI_MSG_DBG);
}
if (emc_debug & EMC_DEBUG_VERSIONS) {
if (NULL != (inistring = inifile.Find("VERSION", "EMC"))) {
if(sscanf(inistring, "$Revision: %s", version) != 1) {
strncpy(version, "unknown", LINELEN-1);
}
} else {
strncpy(version, "unknown", LINELEN-1);
}
if (NULL != (inistring = inifile.Find("MACHINE", "EMC"))) {
strncpy(machine, inistring, LINELEN-1);
} else {
strncpy(machine, "unknown", LINELEN-1);
}
rtapi_print_msg(RTAPI_MSG_DBG,"%s: machine: '%s' version '%s'\n", progname,machine, version);
}
if (NULL != (inistring = inifile.Find("NML_FILE", "EMC"))) {
strcpy(emc_nmlfile, inistring);
} else {
}
double temp;
temp = emc_io_cycle_time;
if (NULL != (inistring = inifile.Find("CYCLE_TIME", "EMCIO"))) {
if (1 == sscanf(inistring, "%lf", &emc_io_cycle_time)) {
} else {
emc_io_cycle_time = temp;
rtapi_print
("invalid [EMCIO] CYCLE_TIME in %s (%s); using default %f\n",
filename, inistring, emc_io_cycle_time);
}
} else {
rtapi_print
("[EMCIO] CYCLE_TIME not found in %s; using default %f\n",
filename, emc_io_cycle_time);
}
inifile.Find(&proto, "PROTOCOL_VERSION", "EMCIO");
rtapi_print_msg(RTAPI_MSG_DBG,"%s: [EMCIO] using v%d protocol\n",progname,proto);
inifile.Find(&random_toolchanger, "RANDOM_TOOLCHANGER", "EMCIO");
inifile.Close();
return 0;
}
static int done = 0;
static void quit(int sig)
{
done = 1;
}
#define BITPIN(dir,fmt,ptr) \
if ((retval = hal_pin_bit_newf(dir,ptr,comp_id, fmt,n)) < 0) { \
sprintf(buf,fmt,n); \
rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: %s - export failed error=%d\n",progname,buf,retval); \
goto HAL_EXIT; \
}
#define S32PIN(dir,fmt,ptr) \
if ((retval = hal_pin_s32_newf(dir,ptr,comp_id, fmt,n)) < 0) { \
sprintf(buf,fmt,n); \
rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: %s - export failed error=%d\n",progname,buf,retval); \
goto HAL_EXIT; \
}
int iocontrol_hal_init(void)
{
int n = 0; int retval = -1;
char buf[100];
if ((comp_id = hal_init("iocontrol")) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,"%s: ERROR: hal_init() failed - error=%d\n",progname,comp_id);
goto FAIL;
}
if ((iocontrol_data = (iocontrol_str *) hal_malloc(sizeof(iocontrol_str))) == NULL) {
rtapi_print_msg(RTAPI_MSG_ERR,"%s: ERROR: hal_malloc() failed\n",progname);
goto HAL_EXIT;
}
BITPIN( HAL_OUT, "iocontrol.%d.user-enable-out", &(iocontrol_data->user_enable_out));
BITPIN( HAL_OUT, "iocontrol.%d.user-request-enable", &(iocontrol_data->user_request_enable));
BITPIN( HAL_OUT, "iocontrol.%d.coolant-flood", &(iocontrol_data->coolant_flood));
BITPIN( HAL_OUT, "iocontrol.%d.coolant-mist", &(iocontrol_data->coolant_mist));
BITPIN( HAL_OUT, "iocontrol.%d.lube", &(iocontrol_data->lube));
S32PIN( HAL_OUT, "iocontrol.%d.tool-number", &(iocontrol_data->tool_number));
S32PIN( HAL_OUT, "iocontrol.%d.tool-prep-number", &(iocontrol_data->tool_prep_number));
S32PIN( HAL_OUT, "iocontrol.%d.tool-prep-pocket", &(iocontrol_data->tool_prep_pocket));
retval = hal_param_s32_newf(HAL_RO, &(iocontrol_data->tool_prep_index), comp_id,
"iocontrol.%d.tool-prep-index", n);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"IOCONTROL: ERROR: iocontrol %d param tool-prep-index export failed with err=%i\n",
n, retval);
hal_exit(comp_id);
return -1;
}
BITPIN( HAL_OUT, "iocontrol.%d.tool-prepare", &(iocontrol_data->tool_prepare));
BITPIN( HAL_IN , "iocontrol.%d.tool-prepared", &(iocontrol_data->tool_prepared));
BITPIN( HAL_OUT, "iocontrol.%d.tool-change", &(iocontrol_data->tool_change));
BITPIN( HAL_IN , "iocontrol.%d.tool-changed", &(iocontrol_data->tool_changed));
BITPIN( HAL_IN , "iocontrol.%d.emc-enable-in", &(iocontrol_data->emc_enable_in));
BITPIN( HAL_IN , "iocontrol.%d.lube_level", &(iocontrol_data->lube_level));
S32PIN( HAL_OUT, "iocontrol.%d.state", &(iocontrol_data->state));
if (proto > V1) {
BITPIN( HAL_OUT, "iocontrol.%d.emc-abort", &(iocontrol_data->emc_abort));
BITPIN( HAL_IN , "iocontrol.%d.emc-abort-ack", &(iocontrol_data->emc_abort_ack));
S32PIN( HAL_OUT, "iocontrol.%d.emc-reason", &(iocontrol_data->emc_reason));
BITPIN( HAL_IN , "iocontrol.%d.toolchanger-fault", &(iocontrol_data->toolchanger_fault));
BITPIN( HAL_OUT, "iocontrol.%d.toolchanger-fault-ack", &(iocontrol_data->toolchanger_fault_ack));
S32PIN( HAL_IN , "iocontrol.%d.toolchanger-reason", &(iocontrol_data->toolchanger_reason));
BITPIN( HAL_OUT, "iocontrol.%d.toolchanger-faulted", &(iocontrol_data->toolchanger_faulted));
BITPIN( HAL_IN , "iocontrol.%d.toolchanger-clear-fault", &(iocontrol_data->toolchanger_clear_fault));
BITPIN( HAL_OUT, "iocontrol.%d.start-change", &(iocontrol_data->start_change));
BITPIN( HAL_IN , "iocontrol.%d.start-change-ack", &(iocontrol_data->start_change_ack));
}
rtapi_print_msg(RTAPI_MSG_DBG, "%s: iocontrol_hal_init() complete\n",progname);
hal_ready(comp_id);
return(0);
HAL_EXIT:
hal_exit(comp_id);
FAIL:
return retval;
}
void hal_init_pins(void)
{
*(iocontrol_data->user_enable_out) = 0;
*(iocontrol_data->user_request_enable) = 0;
*(iocontrol_data->coolant_mist) = 0;
*(iocontrol_data->coolant_flood) = 0;
*(iocontrol_data->lube) = 0;
*(iocontrol_data->tool_prepare) = 0;
*(iocontrol_data->tool_prep_number) = 0;
*(iocontrol_data->tool_prep_pocket) = 0;
iocontrol_data->tool_prep_index = 0;
*(iocontrol_data->tool_change) = 0;
*(iocontrol_data->state) = ST_IDLE;
if (proto > V1) {
*(iocontrol_data->emc_abort) = 0;
*(iocontrol_data->emc_reason) = 0;
*(iocontrol_data->toolchanger_fault_ack) = 0;
*(iocontrol_data->toolchanger_faulted) = 0;
*(iocontrol_data->start_change) = 0;
}
}
void load_tool(int pocket) {
if(random_toolchanger) {
CANON_TOOL_TABLE temp;
char *comment_temp;
temp = emcioStatus.tool.toolTable[0];
emcioStatus.tool.toolTable[0] = emcioStatus.tool.toolTable[pocket];
emcioStatus.tool.toolTable[pocket] = temp;
comment_temp = ttcomments[0];
ttcomments[0] = ttcomments[pocket];
ttcomments[pocket] = comment_temp;
if (0 != saveToolTable(tool_table_file, emcioStatus.tool.toolTable, ttcomments, random_toolchanger))
emcioStatus.status = RCS_ERROR;
} else if (pocket == 0) {
emcioStatus.tool.toolTable[0].toolno = -1;
ZERO_EMC_POSE(emcioStatus.tool.toolTable[0].offset);
emcioStatus.tool.toolTable[0].diameter = 0.0;
emcioStatus.tool.toolTable[0].frontangle = 0.0;
emcioStatus.tool.toolTable[0].backangle = 0.0;
emcioStatus.tool.toolTable[0].orientation = 0;
} else {
emcioStatus.tool.toolTable[0] = emcioStatus.tool.toolTable[pocket];
}
}
void reload_tool_number(int toolno) {
if(random_toolchanger) return; for(int i=1; i<CANON_POCKETS_MAX; i++) {
if(emcioStatus.tool.toolTable[i].toolno == toolno) {
load_tool(i);
break;
}
}
}
static char *str_input(int status)
{
static char seen[200];
seen[0] = 0;
if (status & TI_PREPARING) strcat(seen," TI_PREPARING");
if (status & TI_PREPARE_COMPLETE) strcat(seen," TI_PREPARE_COMPLETE");
if (status & TI_CHANGING) strcat(seen," TI_CHANGING");
if (status & TI_CHANGE_COMPLETE) strcat(seen," TI_CHANGE_COMPLETE");
if (status & TI_TC_FAULT) strcat(seen," TI_TC_FAULT");
if (status & TI_TC_ABORT) strcat(seen," TI_TC_ABORT");
if (status & TI_EMC_ABORT_SIGNALED) strcat(seen," TI_EMC_ABORT_SIGNALED");
if (status & TI_EMC_ABORT_ACKED) strcat(seen," TI_EMC_ABORT_ACKED");
if (status & TI_ESTOP_CHANGED) strcat(seen," TI_ESTOP_CHANGED");
if (status & TI_LUBELEVEL_CHANGED) strcat(seen," TI_LUBELEVEL_CHANGED");
if (status & TI_START_CHANGE) strcat(seen," TI_START_CHANGE");
if (status & TI_START_CHANGE_ACKED) strcat(seen," TI_START_CHANGE_ACKED");
return seen;
}
int read_inputs(void)
{
int oldval, retval = 0;
oldval = emcioStatus.aux.estop;
if ( *(iocontrol_data->emc_enable_in)==0) emcioStatus.aux.estop = 1;
else
emcioStatus.aux.estop = 0;
if (oldval != emcioStatus.aux.estop) {
retval |= TI_ESTOP_CHANGED;
}
oldval = emcioStatus.lube.level;
emcioStatus.lube.level = *(iocontrol_data->lube_level); if (oldval != emcioStatus.lube.level) {
retval |= TI_LUBELEVEL_CHANGED;
}
if (proto > V1) {
if (*iocontrol_data->toolchanger_fault) {
toolchanger_reason = *iocontrol_data->toolchanger_reason;
rtapi_print_msg(RTAPI_MSG_DBG, "%s:read_input: toolchanger fault signaled, reason: %d \n",progname, toolchanger_reason);
*(iocontrol_data->toolchanger_fault_ack) = 1;
*(iocontrol_data->toolchanger_faulted) = 1;
retval |= TI_TC_FAULT;
} else {
*(iocontrol_data->toolchanger_fault_ack) = 0;
}
if (*iocontrol_data->toolchanger_clear_fault) {
*(iocontrol_data->toolchanger_faulted) = 0;
toolchanger_reason = 0;
retval &= ~TI_TC_FAULT;
}
if (*iocontrol_data->emc_abort) {
if (*iocontrol_data->emc_abort_ack) {
*(iocontrol_data->emc_abort) = 0;
*(iocontrol_data->state) = ST_IDLE;
retval |= TI_EMC_ABORT_ACKED;
} else {
retval |= TI_EMC_ABORT_SIGNALED;
}
}
if (*iocontrol_data->start_change) {
if (*iocontrol_data->start_change_ack) {
*(iocontrol_data->start_change) = 0;
retval |= TI_START_CHANGE_ACKED;
} else {
retval |= TI_START_CHANGE;
}
}
}
if (*iocontrol_data->tool_prepare) {
if (*iocontrol_data->tool_prepared) {
emcioStatus.tool.pocketPrepped = iocontrol_data->tool_prep_index; *(iocontrol_data->tool_prepare) = 0;
*(iocontrol_data->state) = ST_IDLE; retval |= TI_PREPARE_COMPLETE;
} else {
*(iocontrol_data->state) = ST_PREPARING;
retval |= TI_PREPARING;
}
}
if (*iocontrol_data->tool_change) {
if ((proto > V1) && (*iocontrol_data->toolchanger_faulted)) {
toolchanger_reason = *iocontrol_data->toolchanger_reason;
*(iocontrol_data->emc_reason) = EMC_ABORT_BY_TOOLCHANGER_FAULT;
*(iocontrol_data->emc_abort) = 1;
retval |= TI_TC_ABORT;
*(iocontrol_data->tool_change) = 0;
*(iocontrol_data->state) = ST_WAIT_FOR_ABORT_ACK;
}
if (*iocontrol_data->tool_changed) {
if(!random_toolchanger && emcioStatus.tool.pocketPrepped == 0) {
emcioStatus.tool.toolInSpindle = 0;
} else {
emcioStatus.tool.toolInSpindle = emcioStatus.tool.toolTable[emcioStatus.tool.pocketPrepped].toolno;
}
*(iocontrol_data->tool_number) = emcioStatus.tool.toolInSpindle; load_tool(emcioStatus.tool.pocketPrepped);
emcioStatus.tool.pocketPrepped = -1; *(iocontrol_data->tool_prep_number) = 0; *(iocontrol_data->tool_prep_pocket) = 0; iocontrol_data->tool_prep_index = 0; *(iocontrol_data->tool_change) = 0; *(iocontrol_data->state) = ST_IDLE;
retval |= TI_CHANGE_COMPLETE;
} else {
retval |= TI_CHANGING;
}
}
return retval;
}
static void do_hal_exit(void) {
hal_exit(comp_id);
}
void update_status(int status, int serial)
{
static int status_reported = -1;
emcioStatus.status = status;
if (status_reported != status) {
rtapi_print_msg(RTAPI_MSG_DBG, "%s: updating status=%s state=%s fault=%d reason=%d\n",
progname,strcs[emcioStatus.status],strstate[*(iocontrol_data->state)],
emcioStatus.fault, emcioStatus.reason
);
status_reported = emcioStatus.status; }
emcioStatus.command_type = EMC_IO_STAT_TYPE;
emcioStatus.echo_serial_number = serial;
emcioStatus.heartbeat++;
emcioStatusBuffer->write(&emcioStatus);
}
int main(int argc, char *argv[])
{
int t, input_status;
NMLTYPE type;
progname = argv[0];
for (t = 1; t < argc; t++) {
if (!strcmp(argv[t], "-support-start-change")) {
support_start_change = 1;
continue;
}
if (!strcmp(argv[t], "-ini")) {
if (t == argc - 1) {
return -1;
} else {
if (strlen(argv[t+1]) >= LINELEN) {
rtapi_print_msg(RTAPI_MSG_ERR, "ini file name too long (max %d)\n", LINELEN);
rtapi_print_msg(RTAPI_MSG_ERR, " %s\n", argv[t+1]);
return -1;
}
strcpy(emc_inifile, argv[t + 1]);
t++;
}
continue;
}
}
signal(SIGINT, quit);
signal(SIGTERM, quit);
if (0 != iniLoad(emc_inifile)) {
rtapi_print_msg(RTAPI_MSG_ERR, "%s: can't open ini file %s\n",progname,emc_inifile);
exit(-1);
}
if (iocontrol_hal_init() != 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "%s: can't initialize the HAL\n",progname);
exit(-1);
}
atexit(do_hal_exit);
if (0 != emcIoNmlGet()) {
rtapi_print_msg(RTAPI_MSG_ERR,
"%s:can't connect to NML buffers in %s\n",progname,emc_inifile);
exit(-1);
}
if (0 != iniTool(emc_inifile)) {
rcs_print_error("%s: iniTool failed.\n",progname);
exit(-1);
}
for(int i = 0; i < CANON_POCKETS_MAX; i++) {
ttcomments[i] = (char *)malloc(CANON_TOOL_ENTRY_LEN);
}
if(!random_toolchanger) {
emcioStatus.tool.toolTable[0].toolno = -1;
ZERO_EMC_POSE(emcioStatus.tool.toolTable[0].offset);
emcioStatus.tool.toolTable[0].diameter = 0.0;
emcioStatus.tool.toolTable[0].frontangle = 0.0;
emcioStatus.tool.toolTable[0].backangle = 0.0;
emcioStatus.tool.toolTable[0].orientation = 0;
ttcomments[0][0] = '\0';
}
if (0 != loadToolTable(tool_table_file, emcioStatus.tool.toolTable,
ttcomments, random_toolchanger)) {
rcs_print_error("%s: can't load tool table.\n",progname);
}
done = 0;
emcioStatus.aux.estop = 1; emcioStatus.tool.pocketPrepped = -1;
emcioStatus.tool.toolInSpindle = 0;
emcioStatus.coolant.mist = 0;
emcioStatus.coolant.flood = 0;
emcioStatus.lube.on = 0;
emcioStatus.lube.level = 1;
while (!done) {
input_status = read_inputs();
emcioStatus.fault = *(iocontrol_data->toolchanger_faulted);
emcioStatus.reason = toolchanger_reason;
if (input_status & (TI_ESTOP_CHANGED|TI_LUBELEVEL_CHANGED)) {
if (input_status & TI_ESTOP_CHANGED) {
rtapi_print_msg(RTAPI_MSG_DBG, "%s:ESTOP changed to %d\n",progname,emcioStatus.aux.estop);
}
if (input_status & TI_LUBELEVEL_CHANGED)
rtapi_print_msg(RTAPI_MSG_DBG, "%s:lube_level changed to %d\n",progname,emcioStatus.lube.level);
update_status(RCS_DONE, emcioCommand->serial_number + 1);
}
if (input_status & (TI_PREPARING)) {
update_status(RCS_EXEC, emcioCommand->serial_number);
}
if (input_status & (TI_START_CHANGE|TI_CHANGING)) {
if (TC_FAULT) {
rtapi_print_msg(RTAPI_MSG_DBG, "%s: signaling fault during change, reason=%d state=%s input_status=%s\n",
progname,
toolchanger_reason,
strstate[*(iocontrol_data->state)],
str_input(input_status)
);
update_status(RCS_ERROR, emcioCommand->serial_number);
} else {
update_status(RCS_EXEC, emcioCommand->serial_number);
}
}
if (input_status & (TI_PREPARE_COMPLETE|TI_CHANGE_COMPLETE|TI_START_CHANGE_ACKED)) {
update_status(RCS_DONE, emcioCommand->serial_number);
}
if (-1 == emcioCommandBuffer->read()) {
esleep(emc_io_cycle_time);
continue;
}
if (0 == emcioCommand || 0 == emcioCommand->type || emcioCommand->serial_number == emcioStatus.echo_serial_number) {
esleep(emc_io_cycle_time);
continue;
}
emcioStatus.status = RCS_DONE;
type = emcioCommand->type;
switch (type) {
case 0:
break;
case EMC_IO_INIT_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_IO_INIT\n");
hal_init_pins();
break;
case EMC_TOOL_INIT_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_INIT\n");
loadToolTable(tool_table_file, emcioStatus.tool.toolTable,
ttcomments, random_toolchanger);
reload_tool_number(emcioStatus.tool.toolInSpindle);
break;
case EMC_TOOL_HALT_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_HALT\n");
break;
case EMC_TOOL_ABORT_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_ABORT reason=%d\n",((EMC_TOOL_ABORT *) emcioCommand)->reason);
emcioStatus.coolant.mist = 0;
emcioStatus.coolant.flood = 0;
*(iocontrol_data->coolant_mist) = 0; *(iocontrol_data->coolant_flood) = 0;
if (proto > V1) {
*(iocontrol_data->emc_reason) = ((EMC_TOOL_ABORT *) emcioCommand)->reason;
*(iocontrol_data->emc_abort) = 1; }
*(iocontrol_data->tool_change) = 0; *(iocontrol_data->tool_prepare) = 0; *(iocontrol_data->start_change) = 0;
*(iocontrol_data->state) = (proto > V1) ? ST_WAIT_FOR_ABORT_ACK : ST_IDLE;
break;
case EMC_TOOL_PREPARE_TYPE:
{
int p = ((EMC_TOOL_PREPARE*)emcioCommand)->pocket;
int t = ((EMC_TOOL_PREPARE*)emcioCommand)->tool;
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_PREPARE tool=%d pocket=%d\n", t, p);
if (random_toolchanger && p == 0)
break;
iocontrol_data->tool_prep_index = p;
*(iocontrol_data->tool_prep_pocket) = random_toolchanger? p: emcioStatus.tool.toolTable[p].pocketno;
if (!random_toolchanger && p == 0) {
*(iocontrol_data->tool_prep_number) = 0;
*(iocontrol_data->tool_prep_pocket) = 0;
} else {
*(iocontrol_data->tool_prep_number) = emcioStatus.tool.toolTable[p].toolno;
if (emcioStatus.tool.toolTable[p].toolno != t) rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_PREPARE: mismatch: tooltable[%d]=%d, got %d\n",
p, emcioStatus.tool.toolTable[p].toolno, t);
}
if ((proto > V1) && *(iocontrol_data->toolchanger_faulted)) { rtapi_print_msg(RTAPI_MSG_DBG, "%s: prepare: toolchanger faulted (reason=%d), next M6 will %s\n",
progname,toolchanger_reason,
toolchanger_reason > 0 ? "set fault code and reason" : "abort program");
}
*(iocontrol_data->tool_prepare) = 1;
*(iocontrol_data->state) = ST_PREPARING;
if (!(input_status & TI_PREPARE_COMPLETE)) {
emcioStatus.status = RCS_EXEC;
}
}
break;
case EMC_TOOL_LOAD_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_LOAD loaded=%d prepped=%d\n", emcioStatus.tool.toolInSpindle, emcioStatus.tool.pocketPrepped);
if (random_toolchanger && emcioStatus.tool.pocketPrepped == 0) {
break;
}
if (!random_toolchanger && emcioStatus.tool.pocketPrepped > 0 &&
emcioStatus.tool.toolInSpindle == emcioStatus.tool.toolTable[emcioStatus.tool.pocketPrepped].toolno) {
break;
}
if (emcioStatus.tool.pocketPrepped != -1) {
*(iocontrol_data->tool_change) = 1;
*(iocontrol_data->state) = ST_CHANGING;
if (! (input_status & TI_CHANGE_COMPLETE)) {
emcioStatus.status = RCS_EXEC;
}
}
break;
case EMC_TOOL_START_CHANGE_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_START_CHANGE\n");
if ((proto > V1) && support_start_change) {
*(iocontrol_data->start_change) = 1;
*(iocontrol_data->state) = ST_START_CHANGE;
if (! (input_status & TI_START_CHANGE_ACKED)) {
emcioStatus.status = RCS_EXEC;
}
}
break;
case EMC_TOOL_UNLOAD_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_UNLOAD\n");
emcioStatus.tool.toolInSpindle = 0;
break;
case EMC_TOOL_LOAD_TOOL_TABLE_TYPE:
{
const char *filename =
((EMC_TOOL_LOAD_TOOL_TABLE *) emcioCommand)->file;
if (!strlen(filename)) filename = tool_table_file;
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_LOAD_TOOL_TABLE\n");
if (0 != loadToolTable(filename, emcioStatus.tool.toolTable,
ttcomments, random_toolchanger))
emcioStatus.status = RCS_ERROR;
else
reload_tool_number(emcioStatus.tool.toolInSpindle);
}
break;
case EMC_TOOL_SET_OFFSET_TYPE:
{
int p, t, o;
double d, f, b;
EmcPose offs;
p = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->pocket;
t = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->toolno;
offs = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->offset;
d = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->diameter;
f = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->frontangle;
b = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->backangle;
o = ((EMC_TOOL_SET_OFFSET *) emcioCommand)->orientation;
rtapi_print_msg(RTAPI_MSG_DBG,
"EMC_TOOL_SET_OFFSET pocket=%d toolno=%d zoffset=%lf, xoffset=%lf, diameter=%lf,"
" frontangle=%lf, backangle=%lf, orientation=%d\n",
p, t, offs.tran.z, offs.tran.x, d, f, b, o);
emcioStatus.tool.toolTable[p].toolno = t;
emcioStatus.tool.toolTable[p].offset = offs;
emcioStatus.tool.toolTable[p].diameter = d;
emcioStatus.tool.toolTable[p].frontangle = f;
emcioStatus.tool.toolTable[p].backangle = b;
emcioStatus.tool.toolTable[p].orientation = o;
if (emcioStatus.tool.toolInSpindle == t) {
emcioStatus.tool.toolTable[0] = emcioStatus.tool.toolTable[p];
}
}
if (0 != saveToolTable(tool_table_file, emcioStatus.tool.toolTable, ttcomments, random_toolchanger))
emcioStatus.status = RCS_ERROR;
break;
case EMC_TOOL_SET_NUMBER_TYPE:
{
int number;
number = ((EMC_TOOL_SET_NUMBER *) emcioCommand)->tool;
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_SET_NUMBER pocket=%d old_loaded=%d new_number=%d\n",
number, emcioStatus.tool.toolInSpindle,
emcioStatus.tool.toolTable[number].toolno);
emcioStatus.tool.toolInSpindle = emcioStatus.tool.toolTable[number].toolno;
load_tool(number);
*(iocontrol_data->tool_number) = emcioStatus.tool.toolInSpindle; }
break;
case EMC_COOLANT_MIST_ON_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_COOLANT_MIST_ON\n");
emcioStatus.coolant.mist = 1;
*(iocontrol_data->coolant_mist) = 1;
break;
case EMC_COOLANT_MIST_OFF_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_COOLANT_MIST_OFF\n");
emcioStatus.coolant.mist = 0;
*(iocontrol_data->coolant_mist) = 0;
break;
case EMC_COOLANT_FLOOD_ON_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_COOLANT_FLOOD_ON\n");
emcioStatus.coolant.flood = 1;
*(iocontrol_data->coolant_flood) = 1;
break;
case EMC_COOLANT_FLOOD_OFF_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_COOLANT_FLOOD_OFF\n");
emcioStatus.coolant.flood = 0;
*(iocontrol_data->coolant_flood) = 0;
break;
case EMC_AUX_ESTOP_ON_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_AUX_ESTOP_ON\n");
*(iocontrol_data->user_enable_out) = 0; hal_init_pins(); break;
case EMC_AUX_ESTOP_OFF_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_AUX_ESTOP_OFF\n");
*(iocontrol_data->user_enable_out) = 1;
*(iocontrol_data->user_request_enable) = 1;
break;
case EMC_AUX_ESTOP_RESET_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_AUX_ESTOP_RESET\n");
break;
case EMC_LUBE_ON_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_LUBE_ON\n");
emcioStatus.lube.on = 1;
*(iocontrol_data->lube) = 1;
break;
case EMC_LUBE_OFF_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_LUBE_OFF\n");
emcioStatus.lube.on = 0;
*(iocontrol_data->lube) = 0;
break;
case EMC_SET_DEBUG_TYPE:
rtapi_print_msg(RTAPI_MSG_DBG, "EMC_SET_DEBUG\n");
emc_debug = ((EMC_SET_DEBUG *) emcioCommand)->debug;
break;
default:
rtapi_print("IO: unknown command %s\n", emcSymbolLookup(type));
break;
}
emcioStatus.command_type = type;
emcioStatus.echo_serial_number = emcioCommand->serial_number;
emcioStatus.heartbeat++;
emcioStatus.reason = toolchanger_reason; emcioStatusBuffer->write(&emcioStatus);
esleep(emc_io_cycle_time);
*(iocontrol_data->user_request_enable) = 0;
}
if (emcErrorBuffer != 0) {
delete emcErrorBuffer;
emcErrorBuffer = 0;
}
if (emcioStatusBuffer != 0) {
delete emcioStatusBuffer;
emcioStatusBuffer = 0;
}
if (emcioCommandBuffer != 0) {
delete emcioCommandBuffer;
emcioCommandBuffer = 0;
}
for(int i=0; i<CANON_POCKETS_MAX; i++) {
free(ttcomments[i]);
}
rtapi_print("%s: exiting\n",progname);
exit(0);
}