?? iocontrol.cc
字號:
/********************************************************************* Description: IoControl.cc* Simply accepts NML messages sent to the IO controller* outputs those to a HAL pin,* and sends back a "Done" message.*** ENABLE logic: this module exports three HAL pins related to ENABLE.* The first is emc-enable-in. It is an input from the HAL, when FALSE,* EMC will go into the STOPPED state (regardless of the state of* the other two pins). When it goes TRUE, EMC will go into the* ESTOP_RESET state (also known as READY).** The second HAL pin is an output to the HAL. It is controlled by* the NML messages ESTOP_ON and ESTOP_OFF, which normally result from* user actions at the GUI. For the simplest system, loop user-enable-out * back to emc-enable-in in the HAL. The GUI controls user-enable-out, and EMC* responds to that once it is looped back.** If external ESTOP inputs are desired, they can be* used in a classicladder rung, in series with user-enable-out.* It will look like this:** -----|UEO|-----|EEST|--+--|EEI|--+--(EEI)----* | |* +--|URE|--+* UEO=user-enable-out* EEST=external ESTOP circuitry* EEI=machine is enabled* URE=user request enable** This will work like this: EMC will be enabled (by EEI, emc-enabled-in),* only if UEO, EEST and EEI are closed. * If any of UEO (user requested stop) or EEST (external estop) have been* opened, then EEI will open aswell.* After restoring normal condition (UEO and EEST closed), an aditional* URE (user-request-enable) is needed, this is either sent by the GUI* (using the EMC_AUX_ESTOP_RESET NML message), or by a hardware button* connected to the ladder driving URE.** NML messages are sent usually from the user hitting F1 on the GUI.* * Derived from a work by Fred Proctor & Will Shackleford** Author:* License: GPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.45 $* $Author: cradek $* $Date: 2007/06/16 16:04:02 $********************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <signal.h>#include "hal.h" /* access to HAL functions/definitions */#include "rtapi.h" /* rtapi_print_msg */#include "rcs.hh" /* RCS_CMD_CHANNEL */#include "emc.hh" /* EMC NML */#include "emc_nml.hh"#include "emcglb.h" /* EMC_NMLFILE, EMC_INIFILE, TOOL_TABLE_FILE */#include "inifile.hh" /* INIFILE */#include "initool.hh" /* iniTool() */#include "nml_oi.hh"#include "timer.hh"#include "rcs_print.hh"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;struct iocontrol_str { hal_bit_t *user_enable_out; /* output, TRUE when EMC wants stop */ hal_bit_t *emc_enable_in; /* input, TRUE on any external stop */ hal_bit_t *user_request_enable; /* output, used to reset ENABLE latch */ hal_bit_t *coolant_mist; /* coolant mist output pin */ hal_bit_t *coolant_flood; /* coolant flood output pin */ hal_bit_t *lube; /* lube output pin */ hal_bit_t *lube_level; /* lube level input pin */ // the following pins are needed for toolchanging //tool-prepare hal_bit_t *tool_prepare; /* output, pin that notifies HAL it needs to prepare a tool */ hal_s32_t *tool_prep_number;/* output, pin that holds the tool number to be prepared, only valid when tool-prepare=TRUE */ hal_s32_t *tool_number; /* output, pin that holds the tool number currently in the spindle */ hal_bit_t *tool_prepared; /* input, pin that notifies that the tool has been prepared */ //tool-change hal_bit_t *tool_change; /* output, notifies a tool-change should happen (emc should be in the tool-change position) */ hal_bit_t *tool_changed; /* input, notifies tool has been changed */ // note: spindle control has been moved to motion} * iocontrol_data; //pointer to the HAL-struct//static iocontrol_struct *iocontrol_data; static int comp_id; /* component ID *//********************************************************************** Description: emcIoNmlGet()* Attempts to connect to NML buffers and set the relevant* pointers.** Return Value: Zero on success or -1 if can not connect to a buffer.** Side Effects: None.** Called By: main()*********************************************************************/static int emcIoNmlGet(){ int retval = 0; /* Try to connect to EMC IO command buffer */ 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 { /* Get our command data structure */ emcioCommand = emcioCommandBuffer->get_address(); } } /* try to connect to EMC IO status buffer */ 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 { /* initialize and write status */ emcioStatus.heartbeat = 0; emcioStatus.command_type = 0; emcioStatus.echo_serial_number = 0; emcioStatus.status = RCS_DONE; emcioStatusBuffer->write(&emcioStatus); } } /* try to connect to EMC error buffer */ 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]; /* Open the ini file */ if (inifile.Open(filename) == false) { return -1; } if (NULL != (inistring = inifile.Find("DEBUG", "EMC"))) { /* copy to global */ if (1 != sscanf(inistring, "%i", &EMC_DEBUG)) { EMC_DEBUG = 0; } } else { /* not found, use default */ EMC_DEBUG = 0; } 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("iocontrol: machine: '%s' version '%s'\n", machine, version); } if (NULL != (inistring = inifile.Find("NML_FILE", "EMC"))) { strcpy(EMC_NMLFILE, inistring); } else { // not found, use default } double temp; temp = EMC_IO_CYCLE_TIME; if (NULL != (inistring = inifile.Find("CYCLE_TIME", "EMCIO"))) { if (1 == sscanf(inistring, "%lf", &EMC_IO_CYCLE_TIME)) { // found it } else { // found, but invalid 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 { // not found, using default rtapi_print ("[EMCIO] CYCLE_TIME not found in %s; using default %f\n", filename, EMC_IO_CYCLE_TIME); } // close it inifile.Close(); return 0;}/********************************************************************** Description: loadToolTable(const char *filename, CANON_TOOL_TABLE toolTable[])* Loads the tool table from file filename into toolTable[] array.* Array is CANON_TOOL_MAX + 1 entries, since 0 is included.** Return Value: Zero on success or -1 if file not found.** Side Effects: Default setting used if the parameter not found in* the ini file.** Called By: main()*********************************************************************/static int loadToolTable(const char *filename, CANON_TOOL_TABLE toolTable[]){ int t; FILE *fp; char buffer[CANON_TOOL_ENTRY_LEN]; const char *name; // check filename if (filename[0] == 0) { name = TOOL_TABLE_FILE; } else { // point to name provided name = filename; } //AJ: for debug reasons //rtapi_print("loadToolTable called with %s\n", filename); // open tool table file if (NULL == (fp = fopen(name, "r"))) { // can't open file return -1; } // clear out tool table for (t = 0; t <= CANON_TOOL_MAX; t++) { // unused tools are 0, 0.0, 0.0 toolTable[t].id = 0; toolTable[t].zoffset = 0.0; toolTable[t].diameter = 0.0; toolTable[t].xoffset = 0.0; toolTable[t].frontangle = 0.0; toolTable[t].backangle = 0.0; toolTable[t].orientation = 0; } /* Override 0's with codes from tool file File format is: <header> <pocket # 0..CANON_TOOL_MAX> <FMS id> <length> <diameter> ... */ // read and discard header if (NULL == fgets(buffer, 256, fp)) { // nothing in file at all rtapi_print("IO: toolfile exists, but is empty\n"); fclose(fp); return -1; } while (!feof(fp)) { int pocket; int id; double zoffset; // AKA length double xoffset; double diameter; double frontangle, backangle; int orientation; // just read pocket, ID, and length offset if (NULL == fgets(buffer, CANON_TOOL_ENTRY_LEN, fp)) { break; } if (sscanf(buffer, "%d %d %lf %lf %lf %lf %lf %d", &pocket, &id, &zoffset, &xoffset, &diameter, &frontangle, &backangle, &orientation) == 8) { if (pocket < 0 || pocket > CANON_TOOL_MAX) { printf("skipping tool: bad pocket number %d\n", pocket); continue; } else { /* lathe tool */ toolTable[pocket].id = id; toolTable[pocket].zoffset = zoffset; toolTable[pocket].xoffset = xoffset; toolTable[pocket].diameter = diameter; toolTable[pocket].frontangle = frontangle; toolTable[pocket].backangle = backangle; toolTable[pocket].orientation = orientation; } } else if (sscanf(buffer, "%d %d %lf %lf", &pocket, &id, &zoffset, &diameter) == 4) { if (pocket < 0 || pocket > CANON_TOOL_MAX) { printf("skipping tool: bad pocket number %d\n", pocket); continue; } else { /* mill tool */ toolTable[pocket].id = id; toolTable[pocket].zoffset = zoffset; toolTable[pocket].diameter = diameter; // these aren't used on a mill toolTable[pocket].frontangle = toolTable[pocket].backangle = 0.0; toolTable[pocket].xoffset = 0.0; toolTable[pocket].orientation = 0; } } else { /* invalid line. skip it silently */ continue; } } // close the file fclose(fp);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -