00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <signal.h>
00037
00038 #include "tcl.h"
00039 #ifdef HAVE_TCL_EXTEND
00040 #include "tclExtend.h"
00041 #endif
00042
00043 #include "tk.h"
00044
00045 #include "rcs.hh"
00046 #include "posemath.h"
00047 #include "emc.hh"
00048 #include "emcglb.h"
00049 #include "emccfg.h"
00050 #include "inifile.h"
00051
00052 #ifdef SUN
00053
00054
00055
00056
00057 extern "C" int matherr();
00058 int *tclDummyMathPtr = (int *) matherr;
00059 #endif
00060
00061 #ifdef LINUX
00062
00063 #include <unistd.h>
00064 #include "cppio.hh"
00065
00066 #else
00067
00068
00069 #define cpp_iopl(level) 0
00070 #define cpp_inb(addr) 0
00071 #define cpp_outb(val,addr)
00072 #define cpp_inw(addr) 0
00073 #define cpp_outw(val,addr)
00074 #define cpp_inl(addr) 0
00075 #define cpp_outl(val,addr)
00076
00077 #endif
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 static RCS_CMD_CHANNEL *emcioCommandBuffer = 0;
00167
00168 static RCS_CMD_MSG * emcioCommand = 0;
00169 static RCS_STAT_CHANNEL *emcioStatusBuffer = 0;
00170 static EMC_IO_STAT emcioStatus;
00171
00172
00173 static NML *emcErrorBuffer = 0;
00174
00175 static int emcIoNmlGet()
00176 {
00177 int retval = 0;
00178
00179
00180 if (emcioCommandBuffer == 0) {
00181 emcioCommandBuffer = new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "tool", EMC_NMLFILE);
00182 if (! emcioCommandBuffer->valid()) {
00183 rcs_print_error("emcToolCmd buffer not available\n");
00184 delete emcioCommandBuffer;
00185 emcioCommandBuffer = 0;
00186 retval = -1;
00187 }
00188 else {
00189
00190 emcioCommand = emcioCommandBuffer->get_address();
00191 }
00192 }
00193
00194
00195 if (emcioStatusBuffer == 0) {
00196 emcioStatusBuffer = new RCS_STAT_CHANNEL(emcFormat, "toolSts", "tool", EMC_NMLFILE);
00197 if (! emcioStatusBuffer->valid()) {
00198 rcs_print_error("toolSts buffer not available\n");
00199 delete emcioStatusBuffer;
00200 emcioStatusBuffer = 0;
00201 retval = -1;
00202 }
00203 else {
00204
00205 emcioStatus.heartbeat = 0;
00206 emcioStatus.command_type = 0;
00207 emcioStatus.echo_serial_number = 0;
00208 emcioStatus.status = RCS_DONE;
00209 emcioStatusBuffer->write(&emcioStatus);
00210 }
00211 }
00212
00213 return retval;
00214 }
00215
00216 static int emcErrorNmlGet()
00217 {
00218 int retval = 0;
00219
00220 if (emcErrorBuffer == 0) {
00221 emcErrorBuffer = new NML(nmlErrorFormat, "emcError", "tool", EMC_NMLFILE);
00222 if (! emcErrorBuffer->valid()) {
00223 rcs_print_error("emcError buffer not available\n");
00224 delete emcErrorBuffer;
00225 emcErrorBuffer = 0;
00226 retval = -1;
00227 }
00228 }
00229
00230 return retval;
00231 }
00232
00233
00234
00235 static int emc_ini(ClientData clientdata,
00236 Tcl_Interp *interp,
00237 int objc,
00238 Tcl_Obj *CONST objv[])
00239 {
00240 INIFILE inifile;
00241 const char *inistring;
00242 const char *varstr, *secstr;
00243
00244 if (objc != 3) {
00245 Tcl_SetResult(interp, "emc_ini: need 'var' and 'section'", TCL_VOLATILE);
00246 return TCL_ERROR;
00247 }
00248
00249
00250 if (-1 == inifile.open(EMC_INIFILE)) {
00251 return -1;
00252 }
00253
00254 varstr = Tcl_GetStringFromObj(objv[1], 0);
00255 secstr = Tcl_GetStringFromObj(objv[2], 0);
00256
00257 if (NULL == (inistring = inifile.find(varstr, secstr))) {
00258 return TCL_OK;
00259 }
00260
00261 Tcl_SetResult(interp, (char *) inistring, TCL_VOLATILE);
00262
00263
00264 inifile.close();
00265
00266 return TCL_OK;
00267 }
00268
00269 static int emc_io_connect(ClientData clientdata,
00270 Tcl_Interp *interp,
00271 int objc,
00272 Tcl_Obj *CONST objv[])
00273 {
00274 double end;
00275 int good;
00276
00277 #define RETRY_TIME 10.0 // seconds to wait for subsystems to come up
00278 #define RETRY_INTERVAL 1.0 // seconds between wait tries for a subsystem
00279
00280 if (objc != 1) {
00281 Tcl_SetResult(interp, "emc_io_connect: need no args\n", TCL_VOLATILE);
00282 return TCL_ERROR;
00283 }
00284 if (! (EMC_DEBUG & EMC_DEBUG_NML)) {
00285 set_rcs_print_destination(RCS_PRINT_TO_NULL);
00286 }
00287 end = RETRY_TIME;
00288 good = 0;
00289 do {
00290 if (0 == emcIoNmlGet()) {
00291 good = 1;
00292 break;
00293 }
00294 esleep(RETRY_INTERVAL);
00295 end -= RETRY_INTERVAL;
00296 } while (end > 0.0);
00297
00298 if (! (EMC_DEBUG & EMC_DEBUG_NML)) {
00299 set_rcs_print_destination(RCS_PRINT_TO_STDOUT);
00300 }
00301
00302 if (! good) {
00303 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00304 return TCL_OK;
00305 }
00306
00307 if (! (EMC_DEBUG & EMC_DEBUG_NML)) {
00308 set_rcs_print_destination(RCS_PRINT_TO_NULL);
00309 }
00310 end = RETRY_TIME;
00311 good = 0;
00312 do {
00313 if (0 == emcErrorNmlGet()) {
00314 good = 1;
00315 break;
00316 }
00317 esleep(RETRY_INTERVAL);
00318 end -= RETRY_INTERVAL;
00319 } while (end > 0.0);
00320
00321 if (! (EMC_DEBUG & EMC_DEBUG_NML)) {
00322 set_rcs_print_destination(RCS_PRINT_TO_STDOUT);
00323 }
00324 if (! good) {
00325 Tcl_SetObjResult(interp,Tcl_NewIntObj(-1));
00326 return TCL_OK;
00327 }
00328
00329 Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
00330 return TCL_OK;
00331 }
00332
00333 static int emc_io_disconnect(ClientData clientdata,
00334 Tcl_Interp *interp,
00335 int objc,
00336 Tcl_Obj *CONST objv[])
00337 {
00338 if (objc != 1) {
00339 Tcl_SetResult(interp, "emc_io_disconnect: need no args\n", TCL_VOLATILE);
00340 return TCL_ERROR;
00341 }
00342
00343 if (emcErrorBuffer != 0) {
00344 delete emcErrorBuffer;
00345 emcErrorBuffer = 0;
00346 }
00347
00348 if (emcioStatusBuffer != 0) {
00349 delete emcioStatusBuffer;
00350 emcioStatusBuffer = 0;
00351 }
00352
00353 if (emcioCommandBuffer != 0) {
00354 delete emcioCommandBuffer;
00355 emcioCommandBuffer = 0;
00356 }
00357
00358 Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
00359 return TCL_OK;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369 static int emc_io_read_command(ClientData clientdata,
00370 Tcl_Interp *interp,
00371 int objc,
00372 Tcl_Obj *CONST objv[])
00373 {
00374 if (objc != 1) {
00375 Tcl_SetResult(interp, "emc_io_read_command: need no args\n", TCL_VOLATILE);
00376 return TCL_ERROR;
00377 }
00378
00379
00380 if (0 == emcioCommandBuffer ||
00381 0 == emcioCommand) {
00382 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00383 return TCL_OK;
00384 }
00385
00386
00387 if (-1 == emcioCommandBuffer->peek()) {
00388 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00389 return TCL_OK;
00390 }
00391
00392 Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
00393 return TCL_OK;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 static int emc_io_get_command(ClientData clientdata,
00413 Tcl_Interp *interp,
00414 int objc,
00415 Tcl_Obj *CONST objv[])
00416 {
00417 NMLTYPE type;
00418 char string[256];
00419
00420 if (objc != 1) {
00421 Tcl_SetResult(interp, "emc_io_read_command: need no args\n", TCL_VOLATILE);
00422 return TCL_ERROR;
00423 }
00424
00425
00426 if (0 == emcioCommand) {
00427 Tcl_SetResult(interp, "none", TCL_VOLATILE);
00428 return TCL_OK;
00429 }
00430
00431 type = emcioCommand->type;
00432 switch (type) {
00433 case 0:
00434 Tcl_SetResult(interp, "none", TCL_VOLATILE);
00435 break;
00436
00437 case EMC_IO_INIT_TYPE:
00438 Tcl_SetResult(interp, "emc_io_init", TCL_VOLATILE);
00439 break;
00440
00441 case EMC_TOOL_INIT_TYPE:
00442 Tcl_SetResult(interp, "emc_tool_init", TCL_VOLATILE);
00443 break;
00444
00445 case EMC_TOOL_HALT_TYPE:
00446 Tcl_SetResult(interp, "emc_tool_halt", TCL_VOLATILE);
00447 break;
00448
00449 case EMC_TOOL_ABORT_TYPE:
00450 Tcl_SetResult(interp, "emc_tool_abort", TCL_VOLATILE);
00451 break;
00452
00453 case EMC_TOOL_PREPARE_TYPE:
00454 sprintf(string, "emc_tool_prepare %d",
00455 ((EMC_TOOL_PREPARE *) emcioCommand)->tool);
00456 Tcl_SetResult(interp, string, TCL_VOLATILE);
00457 break;
00458
00459 case EMC_TOOL_LOAD_TYPE:
00460 Tcl_SetResult(interp, "emc_tool_load", TCL_VOLATILE);
00461 break;
00462
00463 case EMC_TOOL_UNLOAD_TYPE:
00464 Tcl_SetResult(interp, "emc_tool_unload", TCL_VOLATILE);
00465 break;
00466
00467 case EMC_SPINDLE_INIT_TYPE:
00468 Tcl_SetResult(interp, "emc_spindle_init", TCL_VOLATILE);
00469 break;
00470
00471 case EMC_SPINDLE_HALT_TYPE:
00472 Tcl_SetResult(interp, "emc_spindle_halt", TCL_VOLATILE);
00473 break;
00474
00475 case EMC_SPINDLE_ABORT_TYPE:
00476 Tcl_SetResult(interp, "emc_spindle_abort", TCL_VOLATILE);
00477 break;
00478
00479 case EMC_SPINDLE_ON_TYPE:
00480 sprintf(string, "emc_spindle_on %f",
00481 ((EMC_SPINDLE_ON *) emcioCommand)->speed);
00482 Tcl_SetResult(interp, string, TCL_VOLATILE);
00483 break;
00484
00485 case EMC_SPINDLE_OFF_TYPE:
00486 Tcl_SetResult(interp, "emc_spindle_off", TCL_VOLATILE);
00487 break;
00488
00489 case EMC_SPINDLE_FORWARD_TYPE:
00490 Tcl_SetResult(interp, "emc_spindle_forward", TCL_VOLATILE);
00491 break;
00492
00493 case EMC_SPINDLE_REVERSE_TYPE:
00494 Tcl_SetResult(interp, "emc_spindle_reverse", TCL_VOLATILE);
00495 break;
00496
00497 case EMC_SPINDLE_STOP_TYPE:
00498 Tcl_SetResult(interp, "emc_spindle_stop", TCL_VOLATILE);
00499 break;
00500
00501 case EMC_SPINDLE_INCREASE_TYPE:
00502 Tcl_SetResult(interp, "emc_spindle_increase", TCL_VOLATILE);
00503 break;
00504
00505 case EMC_SPINDLE_DECREASE_TYPE:
00506 Tcl_SetResult(interp, "emc_spindle_decrease", TCL_VOLATILE);
00507 break;
00508
00509 case EMC_SPINDLE_CONSTANT_TYPE:
00510 Tcl_SetResult(interp, "emc_spindle_constant", TCL_VOLATILE);
00511 break;
00512
00513 case EMC_SPINDLE_BRAKE_RELEASE_TYPE:
00514 Tcl_SetResult(interp, "emc_spindle_brake_release", TCL_VOLATILE);
00515 break;
00516
00517 case EMC_SPINDLE_BRAKE_ENGAGE_TYPE:
00518 Tcl_SetResult(interp, "emc_spindle_brake_engage", TCL_VOLATILE);
00519 break;
00520
00521 case EMC_COOLANT_INIT_TYPE:
00522 Tcl_SetResult(interp, "emc_coolant_init", TCL_VOLATILE);
00523 break;
00524
00525 case EMC_COOLANT_HALT_TYPE:
00526 Tcl_SetResult(interp, "emc_coolant_halt", TCL_VOLATILE);
00527 break;
00528
00529 case EMC_COOLANT_ABORT_TYPE:
00530 Tcl_SetResult(interp, "emc_coolant_abort", TCL_VOLATILE);
00531 break;
00532
00533 case EMC_COOLANT_MIST_ON_TYPE:
00534 Tcl_SetResult(interp, "emc_coolant_mist_on", TCL_VOLATILE);
00535 break;
00536
00537 case EMC_COOLANT_MIST_OFF_TYPE:
00538 Tcl_SetResult(interp, "emc_coolant_mist_off", TCL_VOLATILE);
00539 break;
00540
00541 case EMC_COOLANT_FLOOD_ON_TYPE:
00542 Tcl_SetResult(interp, "emc_coolant_flood_on", TCL_VOLATILE);
00543 break;
00544
00545 case EMC_COOLANT_FLOOD_OFF_TYPE:
00546 Tcl_SetResult(interp, "emc_coolant_flood_off", TCL_VOLATILE);
00547 break;
00548
00549 case EMC_AUX_INIT_TYPE:
00550 Tcl_SetResult(interp, "emc_aux_init", TCL_VOLATILE);
00551 break;
00552
00553 case EMC_AUX_HALT_TYPE:
00554 Tcl_SetResult(interp, "emc_aux_halt", TCL_VOLATILE);
00555 break;
00556
00557 case EMC_AUX_ABORT_TYPE:
00558 Tcl_SetResult(interp, "emc_aux_abort", TCL_VOLATILE);
00559 break;
00560
00561 case EMC_AUX_ESTOP_ON_TYPE:
00562 Tcl_SetResult(interp, "emc_aux_estop_on", TCL_VOLATILE);
00563 break;
00564
00565 case EMC_AUX_ESTOP_OFF_TYPE:
00566 Tcl_SetResult(interp, "emc_aux_estop_off", TCL_VOLATILE);
00567 break;
00568
00569 case EMC_LUBE_INIT_TYPE:
00570 Tcl_SetResult(interp, "emc_lube_init", TCL_VOLATILE);
00571 break;
00572
00573 case EMC_LUBE_HALT_TYPE:
00574 Tcl_SetResult(interp, "emc_lube_halt", TCL_VOLATILE);
00575 break;
00576
00577 case EMC_LUBE_ABORT_TYPE:
00578 Tcl_SetResult(interp, "emc_lube_abort", TCL_VOLATILE);
00579 break;
00580
00581 case EMC_LUBE_ON_TYPE:
00582 Tcl_SetResult(interp, "emc_lube_on", TCL_VOLATILE);
00583 break;
00584
00585 case EMC_LUBE_OFF_TYPE:
00586 Tcl_SetResult(interp, "emc_lube_off", TCL_VOLATILE);
00587 break;
00588
00589 default:
00590 Tcl_SetResult(interp, (char *) emcSymbolLookup(type), TCL_VOLATILE);
00591 break;
00592 }
00593
00594 return TCL_OK;
00595 }
00596
00597
00598
00599
00600 static int emc_io_get_command_type(ClientData clientdata,
00601 Tcl_Interp *interp,
00602 int objc,
00603 Tcl_Obj *CONST objv[])
00604 {
00605 if (objc != 1) {
00606 Tcl_SetResult(interp, "emc_io_get_command_type: need no args\n", TCL_VOLATILE);
00607 return TCL_ERROR;
00608 }
00609
00610 Tcl_SetObjResult(interp, Tcl_NewIntObj(emcioCommand->type));
00611
00612 return TCL_OK;
00613 }
00614
00615
00616
00617
00618 static int emc_io_get_serial_number(ClientData clientdata,
00619 Tcl_Interp *interp,
00620 int objc,
00621 Tcl_Obj *CONST objv[])
00622 {
00623 if (objc != 1) {
00624 Tcl_SetResult(interp, "emc_io_get_serial_number: need no args\n", TCL_VOLATILE);
00625 return TCL_ERROR;
00626 }
00627
00628 Tcl_SetObjResult(interp, Tcl_NewIntObj(emcioCommand->serial_number));
00629
00630 return TCL_OK;
00631 }
00632
00633 static int emc_io_write_status(ClientData clientdata,
00634 Tcl_Interp *interp,
00635 int objc,
00636 Tcl_Obj *CONST objv[])
00637 {
00638 if (objc != 1) {
00639 Tcl_SetResult(interp, "emc_io_write_status: need no args", TCL_VOLATILE);
00640 return TCL_ERROR;
00641 }
00642
00643 if (0 == emcioStatusBuffer) {
00644 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00645 return TCL_OK;
00646 }
00647
00648 if (0 == emcioStatusBuffer->write(&emcioStatus)) {
00649 Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
00650 }
00651 else {
00652 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00653 }
00654 return TCL_OK;
00655 }
00656
00657 static int emc_io_write_error(ClientData clientdata,
00658 Tcl_Interp *interp,
00659 int objc,
00660 Tcl_Obj *CONST objv[])
00661 {
00662 EMC_OPERATOR_ERROR error_msg;
00663
00664 if (objc != 2) {
00665 Tcl_SetResult(interp, "emc_io_write_error: need error string", TCL_VOLATILE);
00666 return TCL_ERROR;
00667 }
00668
00669 if (0 == emcErrorBuffer) {
00670 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00671 return TCL_OK;
00672 }
00673
00674 strncpy(error_msg.error, Tcl_GetStringFromObj(objv[1], 0), EMC_OPERATOR_ERROR_LEN);
00675 error_msg.error[EMC_OPERATOR_ERROR_LEN - 1] = 0;
00676 if (0 == emcErrorBuffer->write(&error_msg)) {
00677 Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
00678 }
00679 else {
00680 Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
00681 }
00682 return TCL_OK;
00683 }
00684
00685
00686
00687
00688 static int emc_io_status_heartbeat(ClientData clientdata,
00689 Tcl_Interp *interp,
00690 int objc,
00691 Tcl_Obj *CONST objv[])
00692 {
00693 int heartbeat;
00694
00695 if (objc != 2) {
00696 Tcl_SetResult(interp, "emc_io_status_heartbeat: need heartbeat", TCL_VOLATILE);
00697 return TCL_ERROR;
00698 }
00699
00700 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &heartbeat)) {
00701 emcioStatus.heartbeat = heartbeat;
00702 return TCL_OK;
00703 }
00704
00705 Tcl_SetResult(interp, "emc_io_status_heartbeat: bad heartbeat", TCL_VOLATILE);
00706 return TCL_ERROR;
00707 }
00708
00709 static int emc_io_status_command_type(ClientData clientdata,
00710 Tcl_Interp *interp,
00711 int objc,
00712 Tcl_Obj *CONST objv[])
00713 {
00714 int command_type;
00715
00716 if (objc != 2) {
00717 Tcl_SetResult(interp, "emc_io_status_command_type: need command type", TCL_VOLATILE);
00718 return TCL_ERROR;
00719 }
00720
00721 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &command_type)) {
00722 emcioStatus.command_type = command_type;
00723 return TCL_OK;
00724 }
00725
00726 Tcl_SetResult(interp, "emc_io_status_command_type: need command type", TCL_VOLATILE);
00727 return TCL_ERROR;
00728 }
00729
00730 static int emc_io_status_echo_serial_number(ClientData clientdata,
00731 Tcl_Interp *interp,
00732 int objc,
00733 Tcl_Obj *CONST objv[])
00734 {
00735 int echo_serial_number;
00736
00737 if (objc != 2) {
00738 Tcl_SetResult(interp, "emc_io_status_echo_serial_number: need echo serial number", TCL_VOLATILE);
00739 return TCL_ERROR;
00740 }
00741
00742 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &echo_serial_number)) {
00743 emcioStatus.echo_serial_number = echo_serial_number;
00744 return TCL_OK;
00745 }
00746
00747 Tcl_SetResult(interp, "emc_io_status_echo_serial_number: need echo serial number", TCL_VOLATILE);
00748 return TCL_ERROR;
00749 }
00750
00751
00752
00753
00754 static int emc_io_status_status(ClientData clientdata,
00755 Tcl_Interp *interp,
00756 int objc,
00757 Tcl_Obj *CONST objv[])
00758 {
00759 const char *objstr;
00760
00761 if (objc != 2) {
00762 Tcl_SetResult(interp, "emc_io_status: need done | exec | error", TCL_VOLATILE);
00763 return TCL_ERROR;
00764 }
00765
00766 objstr = Tcl_GetStringFromObj(objv[1], 0);
00767 if (! strcmp(objstr, "done")) {
00768 emcioStatus.status = RCS_DONE;
00769 return TCL_OK;
00770 }
00771 else if (! strcmp(objstr, "exec")) {
00772 emcioStatus.status = RCS_EXEC;
00773 return TCL_OK;
00774 }
00775 else if (! strcmp(objstr, "error")) {
00776 emcioStatus.status = RCS_ERROR;
00777 return TCL_OK;
00778 }
00779
00780 Tcl_SetResult(interp, "emc_io_status: need done | exec | error", TCL_VOLATILE);
00781 return TCL_ERROR;
00782 }
00783
00784 static int emc_io_status_estop(ClientData clientdata,
00785 Tcl_Interp *interp,
00786 int objc,
00787 Tcl_Obj *CONST objv[])
00788 {
00789 const char *objstr;
00790
00791 if (objc != 2) {
00792 Tcl_SetResult(interp, "emc_io_status_estop: need on | off", TCL_VOLATILE);
00793 return TCL_ERROR;
00794 }
00795
00796 objstr = Tcl_GetStringFromObj(objv[1], 0);
00797 if (! strcmp(objstr, "on")) {
00798 emcioStatus.aux.estop = 1;
00799 return TCL_OK;
00800 }
00801 else if (! strcmp(objstr, "off")) {
00802 emcioStatus.aux.estop = 0;
00803 return TCL_OK;
00804 }
00805
00806 Tcl_SetResult(interp, "emc_io_status_estop: need on | off", TCL_VOLATILE);
00807 return TCL_ERROR;
00808 }
00809
00810 static int emc_io_status_mist(ClientData clientdata,
00811 Tcl_Interp *interp,
00812 int objc,
00813 Tcl_Obj *CONST objv[])
00814 {
00815 const char *objstr;
00816
00817 if (objc != 2) {
00818 Tcl_SetResult(interp, "emc_io_status_mist: need on | off", TCL_VOLATILE);
00819 return TCL_ERROR;
00820 }
00821
00822 objstr = Tcl_GetStringFromObj(objv[1], 0);
00823 if (! strcmp(objstr, "on")) {
00824 emcioStatus.coolant.mist = 1;
00825 return TCL_OK;
00826 }
00827 else if (! strcmp(objstr, "off")) {
00828 emcioStatus.coolant.mist = 0;
00829 return TCL_OK;
00830 }
00831
00832 Tcl_SetResult(interp, "emc_io_status_mist: need on | off", TCL_VOLATILE);
00833 return TCL_ERROR;
00834 }
00835
00836 static int emc_io_status_flood(ClientData clientdata,
00837 Tcl_Interp *interp,
00838 int objc,
00839 Tcl_Obj *CONST objv[])
00840 {
00841 const char *objstr;
00842
00843 if (objc != 2) {
00844 Tcl_SetResult(interp, "emc_io_status_flood: need on | off", TCL_VOLATILE);
00845 return TCL_ERROR;
00846 }
00847
00848 objstr = Tcl_GetStringFromObj(objv[1], 0);
00849 if (! strcmp(objstr, "on")) {
00850 emcioStatus.coolant.flood = 1;
00851 return TCL_OK;
00852 }
00853 else if (! strcmp(objstr, "off")) {
00854 emcioStatus.coolant.flood = 0;
00855 return TCL_OK;
00856 }
00857
00858 Tcl_SetResult(interp, "emc_io_status_flood: need on | off", TCL_VOLATILE);
00859 return TCL_ERROR;
00860 }
00861
00862 static int emc_io_status_lube(ClientData clientdata,
00863 Tcl_Interp *interp,
00864 int objc,
00865 Tcl_Obj *CONST objv[])
00866 {
00867 const char *objstr;
00868
00869 if (objc != 2) {
00870 Tcl_SetResult(interp, "emc_io_status_lube: need on | off", TCL_VOLATILE);
00871 return TCL_ERROR;
00872 }
00873
00874 objstr = Tcl_GetStringFromObj(objv[1], 0);
00875 if (! strcmp(objstr, "on")) {
00876 emcioStatus.lube.on = 1;
00877 return TCL_OK;
00878 }
00879 else if (! strcmp(objstr, "off")) {
00880 emcioStatus.lube.on = 0;
00881 return TCL_OK;
00882 }
00883
00884 Tcl_SetResult(interp, "emc_io_status_lube: need on | off", TCL_VOLATILE);
00885 return TCL_ERROR;
00886 }
00887
00888 static int emc_io_status_lube_level(ClientData clientdata,
00889 Tcl_Interp *interp,
00890 int objc,
00891 Tcl_Obj *CONST objv[])
00892 {
00893 const char *objstr;
00894
00895 if (objc != 2) {
00896 Tcl_SetResult(interp, "emc_io_status_lube_level: need ok | low", TCL_VOLATILE);
00897 return TCL_ERROR;
00898 }
00899
00900 objstr = Tcl_GetStringFromObj(objv[1], 0);
00901 if (! strcmp(objstr, "ok")) {
00902 emcioStatus.lube.level = 1;
00903 return TCL_OK;
00904 }
00905 else if (! strcmp(objstr, "low")) {
00906 emcioStatus.lube.level = 0;
00907 return TCL_OK;
00908 }
00909
00910 Tcl_SetResult(interp, "emc_io_status_lube_level: need ok | low", TCL_VOLATILE);
00911 return TCL_ERROR;
00912 }
00913
00914 static int emc_io_status_spindle_speed(ClientData clientdata,
00915 Tcl_Interp *interp,
00916 int objc,
00917 Tcl_Obj *CONST objv[])
00918 {
00919 double speed;
00920
00921 if (objc != 2) {
00922 Tcl_SetResult(interp, "emc_io_status_spindle_speed: need speed", TCL_VOLATILE);
00923 return TCL_ERROR;
00924 }
00925
00926 if (TCL_OK == Tcl_GetDoubleFromObj(0, objv[1], &speed)) {
00927 emcioStatus.spindle.speed = speed;
00928 return TCL_OK;
00929 }
00930
00931 Tcl_SetResult(interp, "emc_io_status_spindle_speed: need speed", TCL_VOLATILE);
00932 return TCL_ERROR;
00933 }
00934
00935 static int emc_io_status_spindle_enabled(ClientData clientdata,
00936 Tcl_Interp *interp,
00937 int objc,
00938 Tcl_Obj *CONST objv[])
00939 {
00940 const char *objstr;
00941
00942 if (objc != 2) {
00943 Tcl_SetResult(interp, "emc_io_status_spindle_enabled: need on | off", TCL_VOLATILE);
00944 return TCL_ERROR;
00945 }
00946
00947 objstr = Tcl_GetStringFromObj(objv[1], 0);
00948 if (! strcmp(objstr, "on")) {
00949 emcioStatus.spindle.enabled = 1;
00950 return TCL_OK;
00951 }
00952 else if (! strcmp(objstr, "off")) {
00953 emcioStatus.spindle.enabled = 0;
00954 return TCL_OK;
00955 }
00956
00957 Tcl_SetResult(interp, "emc_io_status_spindle_enabled: need on | off", TCL_VOLATILE);
00958 return TCL_ERROR;
00959 }
00960
00961 static int emc_io_status_spindle_direction(ClientData clientdata,
00962 Tcl_Interp *interp,
00963 int objc,
00964 Tcl_Obj *CONST objv[])
00965 {
00966 int direction;
00967
00968 if (objc != 2) {
00969 Tcl_SetResult(interp, "emc_io_status_spindle_direction: need direction", TCL_VOLATILE);
00970 return TCL_ERROR;
00971 }
00972
00973 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &direction)) {
00974 emcioStatus.spindle.direction = direction;
00975 return TCL_OK;
00976 }
00977
00978 Tcl_SetResult(interp, "emc_io_status_spindle_direction: need direction", TCL_VOLATILE);
00979 return TCL_ERROR;
00980 }
00981
00982 static int emc_io_status_spindle_increasing(ClientData clientdata,
00983 Tcl_Interp *interp,
00984 int objc,
00985 Tcl_Obj *CONST objv[])
00986 {
00987 int increasing;
00988
00989 if (objc != 2) {
00990 Tcl_SetResult(interp, "emc_io_status_spindle_increasing: need increasing", TCL_VOLATILE);
00991 return TCL_ERROR;
00992 }
00993
00994 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &increasing)) {
00995 emcioStatus.spindle.increasing = increasing;
00996 return TCL_OK;
00997 }
00998
00999 Tcl_SetResult(interp, "emc_io_status_spindle_increasing: need increasing", TCL_VOLATILE);
01000 return TCL_ERROR;
01001 }
01002
01003 static int emc_io_status_spindle_brake(ClientData clientdata,
01004 Tcl_Interp *interp,
01005 int objc,
01006 Tcl_Obj *CONST objv[])
01007 {
01008 const char *objstr;
01009
01010 if (objc != 2) {
01011 Tcl_SetResult(interp, "emc_io_status_spindle_brake: need on | off", TCL_VOLATILE);
01012 return TCL_ERROR;
01013 }
01014
01015 objstr = Tcl_GetStringFromObj(objv[1], 0);
01016 if (! strcmp(objstr, "on")) {
01017 emcioStatus.spindle.brake = 1;
01018 return TCL_OK;
01019 }
01020 else if (! strcmp(objstr, "off")) {
01021 emcioStatus.spindle.brake = 0;
01022 return TCL_OK;
01023 }
01024
01025 Tcl_SetResult(interp, "emc_io_status_spindle_brake: need on | off", TCL_VOLATILE);
01026 return TCL_ERROR;
01027 }
01028
01029 static int emc_io_status_tool_prepped(ClientData clientdata,
01030 Tcl_Interp *interp,
01031 int objc,
01032 Tcl_Obj *CONST objv[])
01033 {
01034 int toolPrepped;
01035
01036 if (objc != 2) {
01037 Tcl_SetResult(interp, "emc_io_status_tool_prepped: need tool", TCL_VOLATILE);
01038 return TCL_ERROR;
01039 }
01040
01041 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &toolPrepped)) {
01042 emcioStatus.tool.toolPrepped = toolPrepped;
01043 return TCL_OK;
01044 }
01045
01046 Tcl_SetResult(interp, "emc_io_status_tool_prepped: need tool", TCL_VOLATILE);
01047 return TCL_ERROR;
01048 }
01049
01050 static int emc_io_status_tool_in_spindle(ClientData clientdata,
01051 Tcl_Interp *interp,
01052 int objc,
01053 Tcl_Obj *CONST objv[])
01054 {
01055 int toolInSpindle;
01056
01057 if (objc != 2) {
01058 Tcl_SetResult(interp, "emc_io_status_tool_in_spindle: need tool", TCL_VOLATILE);
01059 return TCL_ERROR;
01060 }
01061
01062 if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &toolInSpindle)) {
01063 emcioStatus.tool.toolInSpindle = toolInSpindle;
01064 return TCL_OK;
01065 }
01066
01067 Tcl_SetResult(interp, "emc_io_status_tool_in_spindle: need tool", TCL_VOLATILE);
01068 return TCL_ERROR;
01069 }
01070
01071
01072
01073 static int unpriv = 0;
01074
01075
01076 static int f_inb(ClientData clientdata,
01077 Tcl_Interp *interp,
01078 int objc,
01079 Tcl_Obj *CONST objv[])
01080 {
01081 long address;
01082
01083 if (objc == 2) {
01084 if (TCL_OK == Tcl_GetLongFromObj(0, objv[1], &address)) {
01085 if (unpriv) {
01086 Tcl_SetObjResult(interp, Tcl_NewIntObj(0xFF));
01087 return TCL_OK;
01088 }
01089 Tcl_SetObjResult(interp, Tcl_NewIntObj((int) cpp_inb(address)));
01090 return TCL_OK;
01091 }
01092 }
01093
01094 Tcl_SetResult(interp, "syntax: inb <address>", TCL_VOLATILE);
01095 return TCL_ERROR;
01096 }
01097
01098
01099 static int f_outb(ClientData clientdata,
01100 Tcl_Interp *interp,
01101 int objc,
01102 Tcl_Obj *CONST objv[])
01103 {
01104 long address;
01105 int value;
01106
01107 if (objc == 3) {
01108 if (TCL_OK == Tcl_GetLongFromObj(0, objv[1], &address) &&
01109 TCL_OK == Tcl_GetIntFromObj(0, objv[2], &value)) {
01110 if (unpriv) {
01111 return TCL_OK;
01112 }
01113 cpp_outb((char) value, address);
01114 return TCL_OK;
01115 }
01116 }
01117
01118 Tcl_SetResult(interp, "syntax: outb <address> <value>", TCL_VOLATILE);
01119 return TCL_ERROR;
01120 }
01121
01122
01123 static int f_inw(ClientData clientdata,
01124 Tcl_Interp *interp,
01125 int objc,
01126 Tcl_Obj *CONST objv[])
01127 {
01128 long address;
01129
01130 if (objc == 2) {
01131 if (TCL_OK == Tcl_GetLongFromObj(0, objv[1], &address)) {
01132 if (unpriv) {
01133 Tcl_SetObjResult(interp, Tcl_NewIntObj(0xFFFF));
01134 return TCL_OK;
01135 }
01136 Tcl_SetObjResult(interp, Tcl_NewIntObj((int) cpp_inw(address)));
01137 return TCL_OK;
01138 }
01139 }
01140
01141 Tcl_SetResult(interp, "syntax: inw <address>", TCL_VOLATILE);
01142 return TCL_ERROR;
01143 }
01144
01145
01146 static int f_outw(ClientData clientdata,
01147 Tcl_Interp *interp,
01148 int objc,
01149 Tcl_Obj *CONST objv[])
01150 {
01151 long address;
01152 int value;
01153
01154 if (objc == 3) {
01155 if (TCL_OK == Tcl_GetLongFromObj(0, objv[1], &address) &&
01156 TCL_OK == Tcl_GetIntFromObj(0, objv[2], &value)) {
01157 if (unpriv) {
01158 return TCL_OK;
01159 }
01160 cpp_outw((short) value, address);
01161 return TCL_OK;
01162 }
01163 }
01164
01165 Tcl_SetResult(interp, "syntax: outw <address> <value>", TCL_VOLATILE);
01166 return TCL_ERROR;
01167 }
01168
01169
01170 static int f_inl(ClientData clientdata,
01171 Tcl_Interp *interp,
01172 int objc,
01173 Tcl_Obj *CONST objv[])
01174 {
01175 long address;
01176
01177 if (objc == 2) {
01178 if (TCL_OK == Tcl_GetLongFromObj(0, objv[1], &address)) {
01179 if (unpriv) {
01180 Tcl_SetObjResult(interp, Tcl_NewLongObj(0xFFFFFFFF));
01181 return TCL_OK;
01182 }
01183 Tcl_SetObjResult(interp, Tcl_NewLongObj(cpp_inl(address)));
01184 return TCL_OK;
01185 }
01186 }
01187
01188 Tcl_SetResult(interp, "syntax: inl <address>", TCL_VOLATILE);
01189 return TCL_ERROR;
01190 }
01191
01192
01193 static int f_outl(ClientData clientdata,
01194 Tcl_Interp *interp,
01195 int objc,
01196 Tcl_Obj *CONST objv[])
01197 {
01198 long address;
01199 long value;
01200
01201 if (objc == 3) {
01202 if (TCL_OK == Tcl_GetLongFromObj(0, objv[1], &address) &&
01203 TCL_OK == Tcl_GetLongFromObj(0, objv[2], &value)) {
01204 if (unpriv) {
01205 return TCL_OK;
01206 }
01207 cpp_outl(value, address);
01208 return TCL_OK;
01209 }
01210 }
01211
01212 Tcl_SetResult(interp, "syntax: outl <address> <value>", TCL_VOLATILE);
01213 return TCL_ERROR;
01214 }
01215
01216 int Tcl_AppInit(Tcl_Interp *interp)
01217 {
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 if (Tcl_Init(interp) == TCL_ERROR) {
01230 return TCL_ERROR;
01231 }
01232
01233 #ifdef HAVE_TCL_EXTEND
01234 if (Tclx_Init(interp) == TCL_ERROR) {
01235 return TCL_ERROR;
01236 }
01237 #endif
01238
01239 if (Tk_Init(interp) == TCL_ERROR) {
01240 return TCL_ERROR;
01241 }
01242
01243
01244
01245
01246
01247
01248 Tcl_CreateObjCommand(interp, "emc_ini", emc_ini, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01249
01250 Tcl_CreateObjCommand(interp, "emc_io_connect", emc_io_connect, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01251
01252 Tcl_CreateObjCommand(interp, "emc_io_disconnect", emc_io_disconnect, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01253
01254 Tcl_CreateObjCommand(interp, "emc_io_read_command", emc_io_read_command, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01255
01256 Tcl_CreateObjCommand(interp, "emc_io_get_command", emc_io_get_command, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01257
01258 Tcl_CreateObjCommand(interp, "emc_io_get_command_type", emc_io_get_command_type, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01259
01260 Tcl_CreateObjCommand(interp, "emc_io_get_serial_number", emc_io_get_serial_number, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01261
01262 Tcl_CreateObjCommand(interp, "emc_io_write_status", emc_io_write_status, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01263
01264 Tcl_CreateObjCommand(interp, "emc_io_write_error", emc_io_write_error, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01265
01266 Tcl_CreateObjCommand(interp, "emc_io_status_heartbeat", emc_io_status_heartbeat, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01267
01268 Tcl_CreateObjCommand(interp, "emc_io_status_command_type", emc_io_status_command_type, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01269
01270 Tcl_CreateObjCommand(interp, "emc_io_status_echo_serial_number", emc_io_status_echo_serial_number, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01271
01272 Tcl_CreateObjCommand(interp, "emc_io_status_status", emc_io_status_status, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01273
01274 Tcl_CreateObjCommand(interp, "emc_io_status_estop", emc_io_status_estop, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01275
01276 Tcl_CreateObjCommand(interp, "emc_io_status_mist", emc_io_status_mist, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01277
01278 Tcl_CreateObjCommand(interp, "emc_io_status_flood", emc_io_status_flood, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01279
01280 Tcl_CreateObjCommand(interp, "emc_io_status_lube", emc_io_status_lube, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01281
01282 Tcl_CreateObjCommand(interp, "emc_io_status_lube_level", emc_io_status_lube_level, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01283
01284 Tcl_CreateObjCommand(interp, "emc_io_status_spindle_speed", emc_io_status_spindle_speed, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01285
01286 Tcl_CreateObjCommand(interp, "emc_io_status_spindle_enabled", emc_io_status_spindle_enabled, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01287
01288 Tcl_CreateObjCommand(interp, "emc_io_status_spindle_direction", emc_io_status_spindle_direction, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01289
01290 Tcl_CreateObjCommand(interp, "emc_io_status_spindle_increasing", emc_io_status_spindle_increasing, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01291
01292 Tcl_CreateObjCommand(interp, "emc_io_status_spindle_brake", emc_io_status_spindle_brake, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01293
01294 Tcl_CreateObjCommand(interp, "emc_io_status_tool_prepped", emc_io_status_tool_prepped, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01295
01296 Tcl_CreateObjCommand(interp, "emc_io_status_tool_in_spindle", emc_io_status_tool_in_spindle, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01297
01298 Tcl_CreateObjCommand(interp, "inb", f_inb, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01299
01300 Tcl_CreateObjCommand(interp, "outb", f_outb, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01301
01302 Tcl_CreateObjCommand(interp, "inw", f_inw, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01303
01304 Tcl_CreateObjCommand(interp, "outw", f_outw, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01305
01306 Tcl_CreateObjCommand(interp, "inl", f_inl, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01307
01308 Tcl_CreateObjCommand(interp, "outl", f_outl, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
01309
01310
01311
01312
01313
01314
01315
01316
01317 Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclmainrc", TCL_GLOBAL_ONLY);
01318
01319
01320 Tcl_SetVar(interp, "EMC_INIFILE", EMC_INIFILE, TCL_GLOBAL_ONLY);
01321
01322 return TCL_OK;
01323 }
01324
01325 static void thisQuit(ClientData clientData)
01326 {
01327
01328
01329 if (emcErrorBuffer != 0) {
01330 delete emcErrorBuffer;
01331 emcErrorBuffer = 0;
01332 }
01333
01334 if (emcioStatusBuffer != 0) {
01335 delete emcioStatusBuffer;
01336 emcioStatusBuffer = 0;
01337 }
01338
01339 if (emcioCommandBuffer != 0) {
01340 delete emcioCommandBuffer;
01341 emcioCommandBuffer = 0;
01342 emcioCommand = 0;
01343 }
01344
01345
01346 cpp_iopl(0);
01347
01348 Tcl_Exit(0);
01349 exit(0);
01350 }
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372 static int iniLoad(const char *filename)
01373 {
01374 INIFILE inifile;
01375 const char *inistring;
01376 char version[INIFILE_MAX_LINELEN];
01377
01378
01379 if (-1 == inifile.open(filename)) {
01380 return -1;
01381 }
01382
01383 if (NULL != (inistring = inifile.find("DEBUG", "EMC"))) {
01384
01385 if (1 != sscanf(inistring, "%i", &EMC_DEBUG)) {
01386 EMC_DEBUG = 0;
01387 }
01388 }
01389 else {
01390
01391 EMC_DEBUG = 0;
01392 }
01393
01394 if (EMC_DEBUG & EMC_DEBUG_VERSIONS) {
01395 if (NULL != (inistring = inifile.find("VERSION", "EMC"))) {
01396
01397 sscanf(inistring, "$Revision: %s", version);
01398 rcs_print("Version: %s\n", version);
01399 }
01400 else {
01401
01402 rcs_print("Version: (not found)\n");
01403 }
01404
01405 if (NULL != (inistring = inifile.find("MACHINE", "EMC"))) {
01406
01407 rcs_print("Machine: %s\n", inistring);
01408 }
01409 else {
01410
01411 rcs_print("Machine: (not found)\n");
01412 }
01413 }
01414
01415 if (NULL != (inistring = inifile.find("NML_FILE", "EMC"))) {
01416
01417 strcpy(EMC_NMLFILE, inistring);
01418 }
01419 else {
01420
01421 }
01422
01423
01424 inifile.close();
01425
01426 return 0;
01427 }
01428
01429 static void sigQuit(int sig)
01430 {
01431 thisQuit((ClientData) 0);
01432 }
01433
01434 int main(int argc, char *argv[])
01435 {
01436
01437 rcs_version_printed = 1;
01438
01439
01440 if (0 != emcGetArgs(argc, argv)) {
01441 rcs_print_error("error in argument list\n");
01442 exit(1);
01443 }
01444
01445
01446 iniLoad(EMC_INIFILE);
01447
01448
01449 unpriv = 0;
01450 if (0 != cpp_iopl(3)) {
01451 fprintf(stderr, "not privileged to access IO-- disabling IO\n");
01452 unpriv = 1;
01453 }
01454
01455
01456 Tcl_CreateExitHandler(thisQuit, (ClientData) 0);
01457
01458
01459 signal(SIGINT, sigQuit);
01460
01461
01462 Tk_Main(argc, argv, Tcl_AppInit);
01463
01464 exit(0);
01465 }