/*-------------------------------------------------------------------------- Some code to connect to a serial port through the SINQ system. Just a wrapper around serialsinq derived from David Maden's EL734 routines. You are free to use and modify this software for noncommercial usage. No warranties or liabilities of any kind taken by me or my employer Very primitive device to send commands to a motor from Tcl Modified version for use within SICS. ----------------------------------------------------------------------------*/ #include "sinq_prototypes.h" /* #include */ #include #include #include #include #include #include "rs232c_def.h" #include "el734_def.h" #include "hardsup/serialsinq.h" #define False 0 #define True 1 /*--------------------------------------------------------------------------- Tcl has a high niceness level. It deletes a command properly when exiting, reinitializing etc. I use this facility to kill off the motor initialised in Controller. ---------------------------------------------------------------------------*/ EXTERN void SerialMurder(ClientData pData) { if (pServ->pReader != NULL) { NetReadRemoveUserSocket(pServ->pReader, SerialGetSocket(&(pData))); } SerialClose(&(pData)); free(pData); } /*------------------ a forward declaration -----------------------------*/ EXTERN int SurielSend(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[]); /*---------------------------------------------------------------------------- Controller is the main entry point for this stuff. It connects to a motor and, on success, creates a new command with the name of the motor. Syntax: Controller name host port channel ---------------------------------------------------------------------------*/ int Controller(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[]) { int iRet; int iPort, iChannel, iMotor; char *pErr = NULL; char pBueffel[80]; void **pData = NULL; /* check arguments */ if (argc < 5) { Tcl_AppendResult(interp, " Insufficient arguments: Controller name host port channel index", (char *) NULL); return TCL_ERROR; } /* convert arguments */ iRet = Tcl_GetInt(interp, argv[3], &iPort); if (iRet == TCL_ERROR) { Tcl_AppendResult(interp, "Need integer value for port", (char *) NULL); return iRet; } iRet = Tcl_GetInt(interp, argv[4], &iChannel); if (iRet == TCL_ERROR) { Tcl_AppendResult(interp, "Need integer value for channel", (char *) NULL); return iRet; } iMotor = 1; /* make a new pointer, initialise EL734st */ pData = malloc(sizeof(void *)); if (pData == NULL) { Tcl_AppendResult(interp, "No memory in SerialSinq", NULL); return TCL_ERROR; } /* check for optional force flag */ if (argc > 5) { iRet = SerialForceOpen(pData, (char *) argv[2], iPort, iChannel); } /* open the motor, finally */ iRet = SerialOpen(pData, (char *) argv[2], iPort, iChannel); if (iRet == 1) { /* success */ /* handle TCL, create new command: the serial line */ Tcl_CreateCommand(interp, strdup(argv[1]), SurielSend, *pData, SerialMurder); strcpy(pBueffel, argv[1]); Tcl_AppendResult(interp, strdup(argv[1]), (char *) NULL); if (pServ->pReader != NULL) { NetReadRegisterUserSocket(pServ->pReader, SerialGetSocket(pData)); } return TCL_OK; } else { SerialError(iRet, pBueffel, 79); Tcl_AppendResult(interp, pBueffel, (char *) NULL); SerialClose(pData); free(pData); return TCL_ERROR; } } /*-------------------------------------------------------------------------- Now, this interprets some commands: -tmo val will set a timeout value for the connection. Everything else will be concatenated and sent to the device. -sendterm text defines the terminator which will be appended automatically to each command. -replyterm text sets the expected reply terminator from the Macintosh Serial Port server. ----------------------------------------------------------------------------*/ EXTERN int SurielSend(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[]) { char pBueffel[256]; char pAnswer[256]; char *pErr = NULL; int iRet, iMSR; int i; void *pData; pData = clientData; if (argc >= 2) { if (strcmp(argv[1], "-tmo") == 0) { if (argc >= 3) { iRet = Tcl_GetInt(interp, argv[2], &iMSR); if (iRet != TCL_OK) { sprintf(pBueffel, "%s is not a valid number", argv[2]); Tcl_AppendResult(interp, pBueffel, NULL); return TCL_ERROR; } SerialConfig(&(pData), iMSR); return TCL_OK; } else { Tcl_AppendResult(interp, "Expected parameter after -tmo", NULL); return TCL_ERROR; } } else if (strcmp(argv[1], "-sendterm") == 0) { if (argc < 3) { Tcl_AppendResult(interp, "Expected parameter after -tmo", NULL); return TCL_ERROR; } iRet = SerialSendTerm(&(pData), (char *) argv[2]); if (iRet != 1) { Tcl_AppendResult(interp, "To many characters for terminator", NULL); return TCL_ERROR; } return TCL_OK; } else if (strcmp(argv[1], "-replyterm") == 0) { if (argc < 3) { Tcl_AppendResult(interp, "Expected parameter after -tmo", NULL); return TCL_ERROR; } iRet = SerialATerm(&(pData), (char *) argv[2]); if (!iRet) { Tcl_AppendResult(interp, "To many characters for terminator", NULL); return TCL_ERROR; } return TCL_OK; } else if (strcmp(argv[1], "-put") == 0) { NetReadResetUser(pServ->pReader, SerialGetSocket(&(pData))); if (argc > 2) { strcpy(pBueffel, argv[2]); } for (i = 3; i < argc; i++) { strcat(pBueffel, " "); strcat(pBueffel, argv[i]); } iRet = SerialSend(&(pData), pBueffel); if (iRet != 1) { Tcl_AppendResult(interp, pAnswer, NULL); return TCL_ERROR; } return TCL_OK; } else if (strcmp(argv[1], "-readable") == 0) { iRet = NetReadReadable(pServ->pReader, SerialGetSocket(&(pData))); if (iRet) { Tcl_AppendResult(interp, "1", NULL); return TCL_OK; } else { Tcl_AppendResult(interp, "0", NULL); return TCL_OK; } } else if (strcmp(argv[1], "-get") == 0) { if (NetReadReadable(pServ->pReader, SerialGetSocket(&(pData)))) { iRet = SerialReceive(&(pData), pAnswer, 255); Tcl_AppendResult(interp, pAnswer, NULL); if (iRet == 1) { return TCL_OK; } else { return TCL_ERROR; } } Tcl_AppendResult(interp, "Not Readable", NULL); return TCL_ERROR; } } if (argc >= 2) { strcpy(pBueffel, argv[1]); } for (i = 2; i < argc; i++) { strcat(pBueffel, " "); strcat(pBueffel, argv[i]); } i = strlen(pBueffel); iRet = SerialWriteRead(&(pData), pBueffel, pAnswer, 254); if (iRet != 1) { Tcl_AppendResult(interp, pAnswer, NULL); return TCL_ERROR; } Tcl_AppendResult(interp, pAnswer, NULL); return TCL_OK; }