////////////////////////////////////////////////////////////////////// // // laserconfig - Configuration Tool for UPN Laser Transceiver // Copyright (c) 2000 Jan Kiszka // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // ////////////////////////////////////////////////////////////////////// // History: 0.1 - first version, quit buggy // 0.2 - serial port setup corrected // - data is read byte-by-byte from port now // 0.3 - added laser control // - improved error messages // 0.4 - added baudrate and sensitivity control // 0.4.1 - minor corrections regarding setitimer() and select() #include #include #include #include #include #include #include int tty; char zero[] = {0, 0}; char buf[] = {0x0B, 0x51, 0x65, 0x70, 0x43, 0x81, 0x90, 0x11}; char echobuf; fd_set rd_set; struct termios settings; struct timeval start, stop; int n; int config = 1; int laserctrl = 0; void CfgError() { fprintf(stderr, "error configuring serial port\n"); exit(1); } void alarmsignal(int signum) { } int ReadCmdLine(int argc, char* argv[]) { int n; int acSwitchUsed = 0; int bSwitchUsed = 0; int sSwitchUsed = 0; int sensitivity; if ((argc < 2) || (strcmp(argv[1], "--help") == 0) || (argc > 7)) return 0; for (n = 2; n < argc; n++) { if (strcmp(argv[n], "-a") == 0) { if (acSwitchUsed) return 0; acSwitchUsed = 1; laserctrl = 1; } else if (strcmp(argv[n], "-c") == 0) { if (acSwitchUsed) return 0; acSwitchUsed = 1; config = 0; laserctrl = 1; } else if (strcmp(argv[n], "-b") == 0) { if (bSwitchUsed) return 0; bSwitchUsed = 1; if (n+1 >= argc) return 0; n++; if (strcmp(argv[n], "19200") == 0) buf[5] = 0x8B; else if (strcmp(argv[n], "38400") == 0) buf[5] = 0x89; else if (strcmp(argv[n], "57600") == 0) buf[5] = 0x83; else if (strcmp(argv[n], "115200") == 0) buf[5] = 0x81; else return 0; } else if (strcmp(argv[n], "-s") == 0) { if (sSwitchUsed) return 0; sSwitchUsed = 1; if (n+1 >= argc) return 0; n++; if (strlen(argv[n]) != 1) return 0; sensitivity = argv[n][0] - '0'; if ((sensitivity >= 1) && (sensitivity <= 7)) buf[2] = 0x61 + sensitivity; else return 0; } else return 0; } return 1; } void ConfigureTransceiver() { if ((cfsetspeed(&settings, B9600) < 0) || (tcsetattr(tty, TCSANOW, &settings) < 0)) CfgError(); write(tty, zero, 1); gettimeofday(&start, NULL);; printf("\npowerup the transceiver now..."); fflush(stdout); tcdrain(tty); gettimeofday(&stop, NULL); if (((stop.tv_sec - start.tv_sec) * 10 + (stop.tv_usec - start.tv_usec) / 100000) < 1) { do { printf("\r " "\rdepower the transceiver first..."); fflush(stdout); sleep(1); printf("\rpowerup the transceiver after some seconds..."); write(tty, zero, 1); gettimeofday(&start, NULL); fflush(stdout); tcdrain(tty); gettimeofday(&stop, NULL); } while (((stop.tv_sec - start.tv_sec) * 10 + (stop.tv_usec - start.tv_usec) / 100000) < 1); } printf("\n\nsending configuration string\a\n"); sleep(1); write(tty, zero, 2); write(tty, buf, sizeof(buf)); tcdrain(tty); FD_ZERO(&rd_set); FD_SET(tty, &rd_set); stop.tv_sec = 2; stop.tv_usec = 0; for (n = 0; n < 8; n++) { if (select(FD_SETSIZE, &rd_set, NULL, NULL, &stop) <= 0) { printf("ERROR: string not echoed correctly (timeout)\n"); exit(2); } if ((read(tty, &echobuf, 1) < 1) || (buf[n] != echobuf)) { printf("ERROR: string not echoed correctly (byte %d is wrong)\n\a\a\a", n+1); exit(2); } } sleep(1); printf("string echoed correctly\a\n" "waiting for transceiver to get ready."); fflush(stdout); tcflush(tty, TCIOFLUSH); if ((cfsetspeed(&settings, B115200) < 0) || (tcsetattr(tty, TCSANOW, &settings) < 0)) CfgError(); while (1) { write(tty, buf, 1); stop.tv_sec = 0; stop.tv_usec = 100000; if (select(FD_SETSIZE, &rd_set, NULL, NULL, &stop) <= 0) break; read(tty, &echobuf, 1); sleep(1); printf("."); fflush(stdout); } printf("\n"); } void LaserControl() { struct termios oldterm, newterm; char buf[1024]; char c = 0; int on = 0; struct itimerval timer; tcgetattr(0, &oldterm); memcpy(&newterm, &oldterm, sizeof(struct termios)); settings.c_cflag &= ~CRTSCTS; if ((cfsetspeed(&settings, B115200) < 0) || (tcsetattr(tty, TCSANOW, &settings) < 0)) CfgError(); printf("\n - toggle laser on/off\n" " - exit program\n\n" "laser is OFF"); fflush(stdout); newterm.c_lflag &= (~ICANON + ~ECHO); newterm.c_cc[VTIME] = 0; newterm.c_cc[VMIN] = 0; tcsetattr(0, TCSANOW, &newterm); timer.it_interval.tv_usec = 20000; timer.it_interval.tv_sec = 0; timer.it_value.tv_usec = 20000; timer.it_value.tv_sec = 0; signal(SIGALRM, &alarmsignal); setitimer(ITIMER_REAL, &timer, NULL); memset(buf, 0xAA, sizeof(buf)); while (c != 27) { if (read(0, &c, 1) == 0) c = 0; else if (c == '\t') { if (on) { on = 0; printf("\rlaser is OFF"); fflush(stdout); } else { on = 1; printf("\r " "\rlaser is ON"); fflush(stdout); } } if (on) write(tty, buf, sizeof(buf)); pause(); } timer.it_value.tv_usec = 0; timer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &timer, NULL); printf("\n"); tcsetattr(0, TCSANOW, &oldterm); } int main(int argc, char* argv[]) { if (!ReadCmdLine(argc, argv)) { printf("laserconfig Version 0.4.1\n\n" "usage: laserconfig serial-device [-a | -c][-b baudrate][-s sensitivity]\n\n" "options: -a configure transceiver, then display laser control menu\n" " -c only display laser control menu\n" " -b baudrate set baudrate: 19200, 38400, 57600 or 115200 (default)\n" " -s sensitivity set sensitivity: 1 (more) - 7 (less), default 4\n\n" "laser control works best at 115200 bps.\n\n" "bug reports to: Jan.Kiszka@web.de\n"); exit(3); } tty = open(argv[1], O_RDWR); if ((tty < 0) || (!isatty(tty))) { fprintf(stderr, "error opening device %s\n", argv[1]); exit(1); } if (tcgetattr(tty, &settings) < 0) CfgError(); settings.c_iflag = 0; settings.c_oflag = 0; settings.c_cflag &= ~(CSIZE + CSTOPB + PARENB); settings.c_cflag |= CRTSCTS + CS8; settings.c_lflag &= ~(ICANON + ECHO + ISIG + IEXTEN); settings.c_cc[VTIME] = 0; settings.c_cc[VMIN] = 1; if (config) ConfigureTransceiver(); if (laserctrl) LaserControl(); close(tty); }