rs232.cpp
Go to the documentation of this file.
00001 /*
00002 ***************************************************************************
00003 *
00004 * Author: Teunis van Beelen
00005 *
00006 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Teunis van Beelen
00007 *
00008 * teuniz@gmail.com
00009 *
00010 ***************************************************************************
00011 *
00012 * This program is free software; you can redistribute it and/or modify
00013 * it under the terms of the GNU General Public License as published by
00014 * the Free Software Foundation version 2 of the License.
00015 *
00016 * This program is distributed in the hope that it will be useful,
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 * GNU General Public License for more details.
00020 *
00021 * You should have received a copy of the GNU General Public License along
00022 * with this program; if not, write to the Free Software Foundation, Inc.,
00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024 *
00025 ***************************************************************************
00026 *
00027 * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
00028 *
00029 ***************************************************************************
00030 */
00031 
00032 
00033 
00034 #include "rs232.h"
00035 
00036 
00037 
00038 #ifdef __linux__   /* Linux */
00039 
00040 
00041 int Cport[22],
00042     error;
00043 
00044 struct termios new_port_settings,
00045        old_port_settings[22];
00046 
00047 char comports[22][13]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3","/dev/ttyS4","/dev/ttyS5",
00048                        "/dev/ttyS6","/dev/ttyS7","/dev/ttyS8","/dev/ttyS9","/dev/ttyS10","/dev/ttyS11",
00049                        "/dev/ttyS12","/dev/ttyS13","/dev/ttyS14","/dev/ttyS15","/dev/ttyUSB0",
00050                        "/dev/ttyUSB1","/dev/ttyUSB2","/dev/ttyUSB3","/dev/ttyUSB4","/dev/ttyUSB5"};
00051 
00052 
00053 int OpenComport(int comport_number, int baudrate)
00054 {
00055   int baudr;
00056 
00057   if((comport_number>21)||(comport_number<0))
00058   {
00059     printf("illegal comport number\n");
00060     return(1);
00061   }
00062 
00063   switch(baudrate)
00064   {
00065     case      50 : baudr = B50;
00066                    break;
00067     case      75 : baudr = B75;
00068                    break;
00069     case     110 : baudr = B110;
00070                    break;
00071     case     134 : baudr = B134;
00072                    break;
00073     case     150 : baudr = B150;
00074                    break;
00075     case     200 : baudr = B200;
00076                    break;
00077     case     300 : baudr = B300;
00078                    break;
00079     case     600 : baudr = B600;
00080                    break;
00081     case    1200 : baudr = B1200;
00082                    break;
00083     case    1800 : baudr = B1800;
00084                    break;
00085     case    2400 : baudr = B2400;
00086                    break;
00087     case    4800 : baudr = B4800;
00088                    break;
00089     case    9600 : baudr = B9600;
00090                    break;
00091     case   19200 : baudr = B19200;
00092                    break;
00093     case   38400 : baudr = B38400;
00094                    break;
00095     case   57600 : baudr = B57600;
00096                    break;
00097     case  115200 : baudr = B115200;
00098                    break;
00099     case  230400 : baudr = B230400;
00100                    break;
00101     case  460800 : baudr = B460800;
00102                    break;
00103     case  500000 : baudr = B500000;
00104                    break;
00105     case  576000 : baudr = B576000;
00106                    break;
00107     case  921600 : baudr = B921600;
00108                    break;
00109     case 1000000 : baudr = B1000000;
00110                    break;
00111     default      : printf("invalid baudrate\n");
00112                    return(1);
00113                    break;
00114   }
00115 
00116   Cport[comport_number] = open(comports[comport_number], O_RDWR | O_NOCTTY | O_NDELAY);
00117   if(Cport[comport_number]==-1)
00118   {
00119     perror("unable to open comport ");
00120     return(1);
00121   }
00122 
00123   error = tcgetattr(Cport[comport_number], old_port_settings + comport_number);
00124   if(error==-1)
00125   {
00126     close(Cport[comport_number]);
00127     perror("unable to read portsettings ");
00128     return(1);
00129   }
00130   memset(&new_port_settings, 0, sizeof(new_port_settings));  /* clear the new struct */
00131 
00132   new_port_settings.c_cflag = baudr | CS8 | CLOCAL | CREAD;
00133   new_port_settings.c_iflag = IGNPAR;
00134   new_port_settings.c_oflag = 0;
00135   new_port_settings.c_lflag = 0;
00136   new_port_settings.c_cc[VMIN] = 0;      /* block untill n bytes are received */
00137   new_port_settings.c_cc[VTIME] = 0;     /* block untill a timer expires (n * 100 mSec.) */
00138   error = tcsetattr(Cport[comport_number], TCSANOW, &new_port_settings);
00139   if(error==-1)
00140   {
00141     close(Cport[comport_number]);
00142     perror("unable to adjust portsettings ");
00143     return(1);
00144   }
00145 
00146   return(0);
00147 }
00148 
00149 
00150 int PollComport(int comport_number, unsigned char *buf, int size)
00151 {
00152   int n;
00153 
00154 #ifndef __STRICT_ANSI__                       /* __STRICT_ANSI__ is defined when the -ansi option is used for gcc */
00155   if(size>SSIZE_MAX)  size = (int)SSIZE_MAX;  /* SSIZE_MAX is defined in limits.h */
00156 #else
00157   if(size>4096)  size = 4096;
00158 #endif
00159 
00160   n = read(Cport[comport_number], buf, size);
00161 
00162   return(n);
00163 }
00164 
00165 
00166 int SendByte(int comport_number, unsigned char byte)
00167 {
00168   int n;
00169 
00170   n = write(Cport[comport_number], &byte, 1);
00171   if(n<0)  return(1);
00172 
00173   return(0);
00174 }
00175 
00176 
00177 int SendBuf(int comport_number, unsigned char *buf, int size)
00178 {
00179   return(write(Cport[comport_number], buf, size));
00180 }
00181 
00182 
00183 void CloseComport(int comport_number)
00184 {
00185   close(Cport[comport_number]);
00186   tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number);
00187 }
00188 
00189 /*
00190 Constant  Description
00191 TIOCM_LE  DSR (data set ready/line enable)
00192 TIOCM_DTR DTR (data terminal ready)
00193 TIOCM_RTS RTS (request to send)
00194 TIOCM_ST  Secondary TXD (transmit)
00195 TIOCM_SR  Secondary RXD (receive)
00196 TIOCM_CTS CTS (clear to send)
00197 TIOCM_CAR DCD (data carrier detect)
00198 TIOCM_CD  Synonym for TIOCM_CAR
00199 TIOCM_RNG RNG (ring)
00200 TIOCM_RI  Synonym for TIOCM_RNG
00201 TIOCM_DSR DSR (data set ready)
00202 */
00203 
00204 int IsCTSEnabled(int comport_number)
00205 {
00206   int status;
00207 
00208   status = ioctl(Cport[comport_number], TIOCMGET, &status);
00209 
00210   if(status&TIOCM_CTS) return(1);
00211   else return(0);
00212 }
00213 
00214 
00215 #else         /* windows */
00216 
00217 
00218 HANDLE Cport[16];
00219 
00220 
00221 char comports[16][10]={"\\\\.\\COM1",  "\\\\.\\COM2",  "\\\\.\\COM3",  "\\\\.\\COM4",
00222                        "\\\\.\\COM5",  "\\\\.\\COM6",  "\\\\.\\COM7",  "\\\\.\\COM8",
00223                        "\\\\.\\COM9",  "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12",
00224                        "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16"};
00225 
00226 char baudr[64];
00227 
00228 
00229 int OpenComport(int comport_number, int baudrate)
00230 {
00231   DCB port_settings;
00232   COMMTIMEOUTS Cptimeouts;
00233   
00234   if((comport_number>15)||(comport_number<0))
00235   {
00236     printf("illegal comport number\n");
00237     return(1);
00238   }
00239 
00240   switch(baudrate)
00241   {
00242     case     110 : strcpy(baudr, "baud=110 data=8 parity=N stop=1");
00243                    break;
00244     case     300 : strcpy(baudr, "baud=300 data=8 parity=N stop=1");
00245                    break;
00246     case     600 : strcpy(baudr, "baud=600 data=8 parity=N stop=1");
00247                    break;
00248     case    1200 : strcpy(baudr, "baud=1200 data=8 parity=N stop=1");
00249                    break;
00250     case    2400 : strcpy(baudr, "baud=2400 data=8 parity=N stop=1");
00251                    break;
00252     case    4800 : strcpy(baudr, "baud=4800 data=8 parity=N stop=1");
00253                    break;
00254     case    9600 : strcpy(baudr, "baud=9600 data=8 parity=N stop=1");
00255                    break;
00256     case   19200 : strcpy(baudr, "baud=19200 data=8 parity=N stop=1");
00257                    break;
00258     case   38400 : strcpy(baudr, "baud=38400 data=8 parity=N stop=1");
00259                    break;
00260     case   57600 : strcpy(baudr, "baud=57600 data=8 parity=N stop=1");
00261                    break;
00262     case  115200 : strcpy(baudr, "baud=115200 data=8 parity=N stop=1");
00263                    break;
00264     case  128000 : strcpy(baudr, "baud=128000 data=8 parity=N stop=1");
00265                    break;
00266     case  256000 : strcpy(baudr, "baud=256000 data=8 parity=N stop=1");
00267                    break;
00268     default      : printf("invalid baudrate\n");
00269                    return(1);
00270                    break;
00271   }
00272 
00273   Cport[comport_number] = CreateFileA(comports[comport_number],
00274                       GENERIC_READ|GENERIC_WRITE,
00275                       0,                          /* no share  */
00276                       NULL,                       /* no security */
00277                       OPEN_EXISTING,
00278                       0,                          /* no threads */
00279                       NULL);                      /* no templates */
00280 
00281   if(Cport[comport_number]==INVALID_HANDLE_VALUE)
00282   {
00283     printf("unable to open comport\n");
00284     return(1);
00285   }
00286 
00287   
00288   memset(&port_settings, 0, sizeof(port_settings));  /* clear the new struct  */
00289   port_settings.DCBlength = sizeof(port_settings);
00290 
00291   if(!BuildCommDCBA(baudr, &port_settings))
00292   {
00293     printf("unable to set comport dcb settings\n");
00294     CloseHandle(Cport[comport_number]);
00295     return(1);
00296   }
00297 
00298   if(!SetCommState(Cport[comport_number], &port_settings))
00299   {
00300     printf("unable to set comport cfg settings\n");
00301     CloseHandle(Cport[comport_number]);
00302     return(1);
00303   }
00304 
00305   Cptimeouts.ReadIntervalTimeout         = MAXDWORD;
00306   Cptimeouts.ReadTotalTimeoutMultiplier  = 0;
00307   Cptimeouts.ReadTotalTimeoutConstant    = 0;
00308   Cptimeouts.WriteTotalTimeoutMultiplier = 0;
00309   Cptimeouts.WriteTotalTimeoutConstant   = 0;
00310 
00311   if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts))
00312   {
00313     printf("unable to set comport time-out settings\n");
00314     CloseHandle(Cport[comport_number]);
00315     return(1);
00316   }
00317 
00318   return(0);
00319 }
00320 
00321 
00322 int PollComport(int comport_number, unsigned char *buf, int size)
00323 {
00324   int n;
00325 
00326   if(size>4096)  size = 4096;
00327 
00328 /* added the void pointer cast, otherwise gcc will complain about */
00329 /* "warning: dereferencing type-punned pointer will break strict aliasing rules" */
00330 
00331   ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL);
00332 
00333   return(n);
00334 }
00335 
00336 
00337 int SendByte(int comport_number, unsigned char byte)
00338 {
00339   int n;
00340 
00341   WriteFile(Cport[comport_number], &byte, 1, (LPDWORD)((void *)&n), NULL);
00342 
00343   if(n<0)  return(1);
00344 
00345   return(0);
00346 }
00347 
00348 
00349 int SendBuf(int comport_number, unsigned char *buf, int size)
00350 {
00351   int n;
00352 
00353   if(WriteFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL))
00354   {
00355     return(n);
00356   }
00357 
00358   return(-1);
00359 }
00360 
00361 
00362 void CloseComport(int comport_number)
00363 {
00364   CloseHandle(Cport[comport_number]);
00365 }
00366 
00367 
00368 int IsCTSEnabled(int comport_number)
00369 {
00370   int status;
00371 
00372   GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
00373 
00374   if(status&MS_CTS_ON) return(1);
00375   else return(0);
00376 }
00377 
00378 
00379 #endif
00380 
00381 
00382 void cprintf(int comport_number, const char *text)  /* sends a string to serial port */
00383 {
00384   while(*text != 0)   SendByte(comport_number, *(text++));
00385 }
00386 
00387 


dynamic
Author(s): wnl
autogenerated on Tue Feb 25 2014 12:52:52