Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

rcxtty.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 2, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 1999
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s): Kekoa Proudfoot  <kekoa@graphics.stanford.edu>
00024  */
00025 
00026 /*  2002.04.01
00027  *
00028  *  Modifications to the original loader.c file in LegOS 0.2.4 include:
00029  *
00030  *  Hary D. Mahesan's update to support USB IR firmware downloading 
00031  *  using RCX 2.0's USB tower under WIN32 on Cygwin.
00032  *      <hdmahesa@engmail.uwaterloo.ca>
00033  *      <hmahesan@hotmail.com>
00034  *
00035  *  CVS inclusion, revision and modification by Paolo Masetti.
00036  *      <paolo.masetti@itlug.org>
00037  *
00038  */
00039 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <fcntl.h>
00043 #include <unistd.h>
00044 
00045 #if defined(_WIN32)
00046   #include <windows.h>
00047 #else
00048   #include <termios.h>
00049   #include <string.h>
00050   #include <errno.h>
00051 #endif
00052 
00053 #include "rcxtty.h"
00054 
00055 extern int tty_usb;
00056 
00058 static FILEDESCR rcxFd = BADFILE;
00059 
00061 FILEDESCR rcxFD(void) {
00062   return rcxFd;
00063 }
00064 
00065 void myperror(char *str) {
00066 #if defined(_WIN32)
00067     fprintf(stderr, "Error %lu: %s\n", (unsigned long) GetLastError(), str);
00068 #else
00069     perror(str);
00070 #endif
00071 }
00072 
00073 int mywrite(FILEDESCR fd, const void *buf, size_t len) {
00074 #if defined(_WIN32)
00075     DWORD nBytesWritten=0;
00076     if (WriteFile(fd, buf, len, &nBytesWritten, NULL))
00077       return nBytesWritten;
00078     else
00079       return -1;
00080 #else
00081    /* For usb tower, the driver, legousbtower, uses interrupt  */
00082    /* urb which can only carry up to 8 bytes at a time. To     */
00083    /* transmit more we have to check and send the rest.  It is */
00084    /* a good thing to check, so I'll make it general.          */
00085    
00086    int actual = 0;
00087    int rc;
00088    char * cptr;
00089    int retry = 1000;
00090    
00091    if (len < 1) return len;
00092    cptr = (char *) buf;
00093    while (actual < len) {
00094       rc = (long) write(fd, cptr+actual, len-actual);
00095       if (rc == -1) {
00096          if ((errno == EINTR) || (errno == EAGAIN))  {
00097             rc = 0;
00098             usleep(10);
00099             retry --;
00100          } else return -1;
00101       }
00102       actual += rc;
00103       if (retry < 1) return actual;
00104    }
00105    return len;
00106 #endif
00107 }
00108 
00110 int rcxInit(const char *tty, int highspeed)
00111 {
00112 /*
00113  *  Copyright (C) 1998, 1999, Kekoa Proudfoot.  All Rights Reserved.
00114  *
00115  *  License to copy, use, and modify this software is granted provided that
00116  *  this notice is retained in any copies of any part of this software.
00117  *
00118  *  The author makes no guarantee that this software will compile or
00119  *  function correctly.  Also, if you use this software, you do so at your
00120  *  own risk.
00121  *
00122  *  Kekoa Proudfoot
00123  *  kekoa@graphics.stanford.edu
00124  *  10/3/98
00125  */
00126 
00127 //  char                *tty;
00128   FILEDESCR     fd;
00129 
00130   #if defined(_WIN32)
00131     DCB dcb;
00132     COMMTIMEOUTS CommTimeouts;
00133   #else
00134     struct termios ios;
00135   #endif
00136 
00137   if (*tty == '-' && !*(tty + 1))  // read from standard input if tty="-"
00138     fd = 0;
00139 #if defined(_WIN32)
00140   else if ((fd = CreateFile(tty, GENERIC_READ | GENERIC_WRITE,
00141                                  0, NULL, OPEN_EXISTING,
00142                                  0, NULL)) == INVALID_HANDLE_VALUE) {
00143     fprintf(stderr, "Error %lu: Opening %s\n", (unsigned long) GetLastError(), tty);
00144 #else
00145   else if ((fd = open(tty, O_RDWR | O_EXCL)) < 0) {
00146     fprintf(stderr,"Error opening tty=%s, ",tty);
00147     perror("open");
00148 #endif
00149     return -1;
00150   }
00151 
00152 #if !defined(_WIN32)
00153   if (tty_usb == 0 && !isatty(fd)) {
00154     close(fd);
00155     fprintf(stderr, "%s: not a tty\n", tty);
00156     return -1;
00157   }
00158 #endif
00159 
00160 #if defined(_WIN32)
00161   // These settings below definitely do not apply to the USB IR Tower, so if() them out.
00162   if(tty_usb==0) {
00163     // Serial settings
00164     FillMemory(&dcb, sizeof(dcb), 0);
00165     if (!GetCommState(fd, &dcb)) {      // get current DCB
00166       // Error in GetCommState
00167       myperror("GetCommState");
00168       return -1;
00169     } else {
00170       dcb.ByteSize = 8;
00171       dcb.Parity   = (highspeed ? 0 : 1);               // 0-4=no,odd,even,mark,space
00172       dcb.StopBits = 0;                                 // 0,1,2 = 1, 1.5, 2
00173       dcb.fBinary  = TRUE ;
00174       dcb.fParity  = FALSE ;
00175       dcb.fAbortOnError = FALSE ;
00176       dcb.BaudRate = (highspeed ? CBR_4800 : CBR_2400); // Update DCB rate.
00177 
00178       // Set new state.
00179       if (!SetCommState(fd, &dcb)) {
00180         // Error in SetCommState. Possibly a problem with the communications
00181         // port handle or a problem with the DCB structure itself.
00182         myperror("SetCommState");
00183         return -1;
00184       }
00185       if (!GetCommTimeouts (fd, &CommTimeouts)) myperror("GetCommTimeouts");
00186 
00187       // Change the COMMTIMEOUTS structure settings.
00188       CommTimeouts.ReadIntervalTimeout = MAXDWORD;
00189       CommTimeouts.ReadTotalTimeoutMultiplier = 0;
00190       CommTimeouts.ReadTotalTimeoutConstant = 0;
00191       CommTimeouts.WriteTotalTimeoutMultiplier = 10;
00192       CommTimeouts.WriteTotalTimeoutConstant = 1000;
00193 
00194       // Set the time-out parameters for all read and write operations
00195       // on the port.
00196       if (!SetCommTimeouts(fd, &CommTimeouts)) myperror("SetCommTimeouts");
00197     }
00198   }
00199   rcxFd=fd;
00200 #else
00201   if (tty_usb == 0) {
00202   memset(&ios, 0, sizeof(ios));
00203   ios.c_cflag = CREAD | CLOCAL | CS8 | (highspeed ? 0 : PARENB | PARODD);
00204 
00205   cfsetispeed(&ios, highspeed ? B4800 : B2400);
00206   cfsetospeed(&ios, highspeed ? B4800 : B2400);
00207 
00208   if (tcsetattr(fd, TCSANOW, &ios) == -1) {
00209     perror("tcsetattr");
00210     exit(1);
00211      }
00212   }
00213   rcxFd=fd;
00214 #endif
00215 
00216   return 0;
00217 }
00218 
00220 void rcxShutdown()
00221 {
00222   #if defined(_WIN32)
00223     CloseHandle(rcxFd);
00224   #else
00225     close(rcxFd);
00226   #endif
00227 
00228   rcxFd=BADFILE;
00229 }

Generated on Fri Feb 25 08:02:39 2005 for brickos by  doxygen 1.3.9.1