cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | #module for serial IO for POSIX compatible systems, like Linux |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 3 | #see __init__.py |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 4 | # |
cliechti | e418ee1 | 2002-05-01 15:22:51 +0000 | [diff] [blame] | 5 | #(C) 2001-2002 Chris Liechti <cliechti@gmx.net> |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 6 | # this is distributed under a free software license, see license.txt |
| 7 | # |
| 8 | #parts based on code from Grant B. Edwards <grante@visi.com>: |
| 9 | # ftp://ftp.visi.com/users/grante/python/PosixSerial.py |
| 10 | # references: http://www.easysw.com/~mike/serial/serial.html |
| 11 | |
| 12 | import sys, os, fcntl, termios, struct, string, select |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 13 | import serialutil |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 14 | |
cliechti | 6ce7ab1 | 2002-11-07 02:15:00 +0000 | [diff] [blame^] | 15 | VERSION = string.split("$Revision: 1.12 $")[1] #extract CVS version |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 16 | |
| 17 | PARITY_NONE, PARITY_EVEN, PARITY_ODD = range(3) |
| 18 | STOPBITS_ONE, STOPBITS_TWO = (1, 2) |
| 19 | FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5,6,7,8) |
| 20 | |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 21 | #Do check the Python version as some constants have moved. |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 22 | if (sys.hexversion < 0x020100f0): |
| 23 | import TERMIOS |
| 24 | else: |
| 25 | TERMIOS = termios |
| 26 | |
| 27 | if (sys.hexversion < 0x020200f0): |
| 28 | import FCNTL |
| 29 | else: |
| 30 | FCNTL = fcntl |
| 31 | |
| 32 | #try to detect the os so that a device can be selected... |
| 33 | plat = string.lower(sys.platform) |
| 34 | |
| 35 | if plat[:5] == 'linux': #Linux (confirmed) |
| 36 | def device(port): |
| 37 | return '/dev/ttyS%d' % port |
| 38 | |
cliechti | f281fde | 2002-06-07 21:53:40 +0000 | [diff] [blame] | 39 | elif plat == 'cygwin': #cywin/win32 (confirmed) |
| 40 | def device(port): |
| 41 | return '/dev/com%d' % port |
| 42 | |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 43 | elif plat == 'openbsd3': #BSD (confirmed) |
| 44 | def device(port): |
| 45 | return '/dev/ttyp%d' % port |
| 46 | |
| 47 | elif plat[:3] == 'bsd' or \ |
| 48 | plat[:6] == 'netbsd' or \ |
| 49 | plat[:7] == 'freebsd' or \ |
| 50 | plat[:7] == 'openbsd' or \ |
| 51 | plat[:6] == 'darwin': #BSD (confirmed for freebsd4: cuaa%d) |
| 52 | def device(port): |
| 53 | return '/dev/cuaa%d' % port |
| 54 | |
| 55 | elif plat[:4] == 'irix': #IRIX® (not tested) |
| 56 | def device(port): |
| 57 | return '/dev/ttyf%d' % port |
| 58 | |
| 59 | elif plat[:2] == 'hp': #HP-UX (not tested) |
| 60 | def device(port): |
| 61 | return '/dev/tty%dp0' % (port+1) |
| 62 | |
cliechti | e418ee1 | 2002-05-01 15:22:51 +0000 | [diff] [blame] | 63 | elif plat[:5] == 'sunos': #Solaris®/SunOS® (confirmed) |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 64 | def device(port): |
| 65 | return '/dev/tty%c' % (ord('a')+port) |
| 66 | |
| 67 | elif plat[:3] == 'dgux': #Digital UNIX® (not tested) |
| 68 | def device(port): |
| 69 | return '/dev/tty0%d' % (port+1) |
| 70 | |
| 71 | else: |
| 72 | #platform detection has failed... |
| 73 | info = "sys.platform = %r\nos.name = %r\nserialposix.py version = %s" % (sys.platform, os.name, VERSION) |
| 74 | print """send this information to the author of this module: |
| 75 | |
| 76 | %s |
| 77 | |
| 78 | also add the device name of the serial port and where the |
| 79 | counting starts for the first serial port. |
| 80 | e.g. 'first serial port: /dev/ttyS0' |
| 81 | and with a bit luck you can get this module running... |
| 82 | """ |
| 83 | raise Exception, "this module does not run on this platform, sorry." |
| 84 | |
| 85 | #whats up with "aix", "beos", "sco", .... |
| 86 | #they should work, just need to know the device names. |
| 87 | #"cygwin" has a POSIX emulation but does not seem to have a /dev/ttyxx structure? |
| 88 | |
| 89 | |
| 90 | # construct dictionaries for baud rate lookups |
| 91 | baudEnumToInt = {} |
| 92 | baudIntToEnum = {} |
| 93 | for rate in (0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600, |
| 94 | 19200,38400,57600,115200,230400,460800,500000,576000,921600, |
| 95 | 1000000,1152000,1500000,2000000,2500000,3000000,3500000,4000000 |
| 96 | ): |
| 97 | try: |
| 98 | i = eval('TERMIOS.B'+str(rate)) |
| 99 | baudEnumToInt[i]=rate |
| 100 | baudIntToEnum[rate] = i |
| 101 | except: |
| 102 | pass |
| 103 | |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 104 | #load some constants for late use |
| 105 | if hasattr(TERMIOS, 'TIOCMGET'): #if this const is here the others will be to (hopefully) |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 106 | TIOCMGET = TERMIOS.TIOCMGET |
| 107 | TIOCMBIS = TERMIOS.TIOCMBIS |
| 108 | TIOCMBIC = TERMIOS.TIOCMBIC |
| 109 | TIOCMSET = TERMIOS.TIOCMSET |
| 110 | |
cliechti | a3ca541 | 2002-02-14 18:44:01 +0000 | [diff] [blame] | 111 | # TIOCM_LE = TERMIOS.TIOCM_LE |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 112 | TIOCM_DTR = TERMIOS.TIOCM_DTR |
| 113 | TIOCM_RTS = TERMIOS.TIOCM_RTS |
cliechti | a3ca541 | 2002-02-14 18:44:01 +0000 | [diff] [blame] | 114 | # TIOCM_ST = TERMIOS.TIOCM_ST |
| 115 | # TIOCM_SR = TERMIOS.TIOCM_SR |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 116 | TIOCM_CTS = TERMIOS.TIOCM_CTS |
| 117 | TIOCM_CAR = TERMIOS.TIOCM_CAR |
| 118 | TIOCM_RNG = TERMIOS.TIOCM_RNG |
| 119 | TIOCM_DSR = TERMIOS.TIOCM_DSR |
| 120 | TIOCM_CD = TERMIOS.TIOCM_CD |
| 121 | TIOCM_RI = TERMIOS.TIOCM_RI |
cliechti | a3ca541 | 2002-02-14 18:44:01 +0000 | [diff] [blame] | 122 | # TIOCM_OUT1 = TERMIOS.TIOCM_OUT1 |
| 123 | # TIOCM_OUT2 = TERMIOS.TIOCM_OUT2 |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 124 | else: #workaround for older python versions |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 125 | TIOCMGET = 0x5415 |
| 126 | TIOCMBIS = 0x5416 |
| 127 | TIOCMBIC = 0x5417 |
| 128 | TIOCMSET = 0x5418 |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 129 | |
cliechti | a3ca541 | 2002-02-14 18:44:01 +0000 | [diff] [blame] | 130 | # TIOCM_LE = 0x001 |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 131 | TIOCM_DTR = 0x002 |
| 132 | TIOCM_RTS = 0x004 |
cliechti | a3ca541 | 2002-02-14 18:44:01 +0000 | [diff] [blame] | 133 | # TIOCM_ST = 0x008 |
| 134 | # TIOCM_SR = 0x010 |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 135 | TIOCM_CTS = 0x020 |
| 136 | TIOCM_CAR = 0x040 |
| 137 | TIOCM_RNG = 0x080 |
| 138 | TIOCM_DSR = 0x100 |
| 139 | TIOCM_CD = TIOCM_CAR |
| 140 | TIOCM_RI = TIOCM_RNG |
cliechti | a3ca541 | 2002-02-14 18:44:01 +0000 | [diff] [blame] | 141 | # TIOCM_OUT1 = 0x2000 |
| 142 | # TIOCM_OUT2 = 0x4000 |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 143 | |
| 144 | TIOCM_zero_str = struct.pack('I', 0) |
| 145 | TIOCM_RTS_str = struct.pack('I', TIOCM_RTS) |
| 146 | TIOCM_DTR_str = struct.pack('I', TIOCM_DTR) |
| 147 | |
| 148 | portNotOpenError = ValueError('port not open') |
| 149 | |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 150 | class Serial(serialutil.FileLike): |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 151 | def __init__(self, |
| 152 | port, #number of device, numbering starts at |
| 153 | #zero. if everything fails, the user |
| 154 | #can specify a device string, note |
| 155 | #that this isn't portable anymore |
| 156 | baudrate=9600, #baudrate |
| 157 | bytesize=EIGHTBITS, #number of databits |
| 158 | parity=PARITY_NONE, #enable parity checking |
| 159 | stopbits=STOPBITS_ONE, #number of stopbits |
| 160 | timeout=None, #set a timeout value, None for waiting forever |
| 161 | xonxoff=0, #enable software flow control |
| 162 | rtscts=0, #enable RTS/CTS flow control |
| 163 | ): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 164 | """init comm port""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 165 | self.fd = None |
| 166 | self.timeout = timeout |
| 167 | vmin = vtime = 0 #timeout is done via select |
| 168 | #open |
| 169 | if type(port) == type(''): #strings are taken directly |
| 170 | self.portstr = port |
| 171 | else: |
cliechti | 6ce7ab1 | 2002-11-07 02:15:00 +0000 | [diff] [blame^] | 172 | self.portstr = device(port) #numbers are transformed to a os dependant string |
cliechti | 4616bf1 | 2002-04-08 23:13:14 +0000 | [diff] [blame] | 173 | try: |
| 174 | self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK) |
| 175 | except Exception, msg: |
| 176 | self.fd = None |
| 177 | raise serialutil.SerialException, "could not open port: %s" % msg |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 178 | fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) #set blocking |
cliechti | 6ce7ab1 | 2002-11-07 02:15:00 +0000 | [diff] [blame^] | 179 | try: |
| 180 | self.__tcgetattr() #read current settings |
| 181 | except termios.error, msg: #if a port is nonexistent but has a /dev file, it'll fail here |
| 182 | raise serialutil.SerialException, "could not open port: %s" % msg |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 183 | #set up raw mode / no echo / binary |
| 184 | self.cflag = self.cflag | (TERMIOS.CLOCAL|TERMIOS.CREAD) |
| 185 | self.lflag = self.lflag & ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL| |
cliechti | f281fde | 2002-06-07 21:53:40 +0000 | [diff] [blame] | 186 | TERMIOS.ECHOCTL|TERMIOS.ECHOKE|TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 187 | self.oflag = self.oflag & ~(TERMIOS.OPOST) |
| 188 | if hasattr(TERMIOS, 'IUCLC'): |
| 189 | self.iflag = self.iflag & ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IUCLC|TERMIOS.IGNBRK) |
| 190 | else: |
| 191 | self.iflag = self.iflag & ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK) |
| 192 | #setup baudrate |
| 193 | try: |
| 194 | self.ispeed = self.ospeed = baudIntToEnum[baudrate] |
| 195 | except: |
| 196 | raise ValueError,'invalid baud rate: %s' % baudrate |
| 197 | #setup char len |
| 198 | self.cflag = self.cflag & ~TERMIOS.CSIZE |
| 199 | if bytesize == 8: |
| 200 | self.cflag = self.cflag | TERMIOS.CS8 |
| 201 | elif bytesize == 7: |
| 202 | self.cflag = self.cflag | TERMIOS.CS7 |
| 203 | elif bytesize == 6: |
| 204 | self.cflag = self.cflag | TERMIOS.CS6 |
| 205 | elif bytesize == 5: |
| 206 | self.cflag = self.cflag | TERMIOS.CS5 |
| 207 | else: |
| 208 | raise ValueError,'invalid char len: '+str(clen) |
| 209 | #setup stopbits |
| 210 | if stopbits == STOPBITS_ONE: |
| 211 | self.cflag = self.cflag & ~(TERMIOS.CSTOPB) |
| 212 | elif stopbits == STOPBITS_TWO: |
| 213 | self.cflag = self.cflag | (TERMIOS.CSTOPB) |
| 214 | else: |
| 215 | raise ValueError,'invalid stopit specification:'+str(stopbits) |
| 216 | #setup parity |
| 217 | self.iflag = self.iflag & ~(TERMIOS.INPCK|TERMIOS.ISTRIP) |
| 218 | if parity == PARITY_NONE: |
| 219 | self.cflag = self.cflag & ~(TERMIOS.PARENB|TERMIOS.PARODD) |
| 220 | elif parity == PARITY_EVEN: |
| 221 | self.cflag = self.cflag & ~(TERMIOS.PARODD) |
| 222 | self.cflag = self.cflag | (TERMIOS.PARENB) |
| 223 | elif parity == PARITY_ODD: |
| 224 | self.cflag = self.cflag | (TERMIOS.PARENB|TERMIOS.PARODD) |
| 225 | else: |
| 226 | raise ValueError,'invalid parity: '+str(par) |
| 227 | #setup flow control |
| 228 | #xonxoff |
| 229 | if hasattr(TERMIOS, 'IXANY'): |
| 230 | if xonxoff: |
| 231 | self.iflag = self.iflag | (TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY) |
| 232 | else: |
| 233 | self.iflag = self.iflag & ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY) |
| 234 | else: |
| 235 | if xonxoff: |
| 236 | self.iflag = self.iflag | (TERMIOS.IXON|TERMIOS.IXOFF) |
| 237 | else: |
| 238 | self.iflag = self.iflag & ~(TERMIOS.IXON|TERMIOS.IXOFF) |
| 239 | #rtscts |
| 240 | if hasattr(TERMIOS, 'CRTSCTS'): |
| 241 | if rtscts: |
| 242 | self.cflag = self.cflag | (TERMIOS.CRTSCTS) |
| 243 | else: |
| 244 | self.cflag = self.cflag & ~(TERMIOS.CRTSCTS) |
cliechti | d474369 | 2002-04-08 22:39:53 +0000 | [diff] [blame] | 245 | elif hasattr(TERMIOS, 'CNEW_RTSCTS'): #try it with alternate constant name |
cliechti | 09cadc6 | 2002-04-08 23:31:01 +0000 | [diff] [blame] | 246 | if rtscts: |
cliechti | d474369 | 2002-04-08 22:39:53 +0000 | [diff] [blame] | 247 | self.cflag = self.cflag | (TERMIOS.CNEW_RTSCTS) |
| 248 | else: |
| 249 | self.cflag = self.cflag & ~(TERMIOS.CNEW_RTSCTS) |
| 250 | #XXX should there be a warning if setting up rtscts (and xonxoff etc) fails?? |
| 251 | |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 252 | #buffer |
| 253 | #vmin "minimal number of characters to be read. = for non blocking" |
| 254 | if vmin<0 or vmin>255: |
| 255 | raise ValueError,'invalid vmin: '+str(vmin) |
| 256 | self.cc[TERMIOS.VMIN] = vmin |
| 257 | #vtime |
| 258 | if vtime<0 or vtime>255: |
| 259 | raise ValueError,'invalid vtime: '+str(vtime) |
| 260 | self.cc[TERMIOS.VTIME] = vtime |
| 261 | #activate settings |
| 262 | self.__tcsetattr() |
| 263 | |
| 264 | def __tcsetattr(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 265 | """internal function to set port attributes""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 266 | termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [self.iflag,self.oflag,self.cflag,self.lflag,self.ispeed,self.ospeed,self.cc]) |
| 267 | |
| 268 | def __tcgetattr(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 269 | """internal function to get port attributes""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 270 | self.iflag,self.oflag,self.cflag,self.lflag,self.ispeed,self.ospeed,self.cc = termios.tcgetattr(self.fd) |
| 271 | |
| 272 | def close(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 273 | """close port""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 274 | if self.fd: |
| 275 | os.close(self.fd) |
| 276 | self.fd = None |
| 277 | |
cliechti | 95c6221 | 2002-03-04 22:17:53 +0000 | [diff] [blame] | 278 | def setBaudrate(self, baudrate): |
| 279 | """change baudrate after port is open""" |
| 280 | if not self.fd: raise portNotOpenError |
| 281 | self.__tcgetattr() #read current settings |
| 282 | #setup baudrate |
| 283 | try: |
| 284 | self.ispeed = self.ospeed = baudIntToEnum[baudrate] |
| 285 | except: |
| 286 | raise ValueError,'invalid baud rate: %s' % baudrate |
| 287 | self.__tcsetattr() |
| 288 | |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 289 | def inWaiting(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 290 | """how many character are in the input queue""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 291 | s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str) |
| 292 | return struct.unpack('I',s)[0] |
| 293 | |
| 294 | def write(self, data): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 295 | """write a string to the port""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 296 | if not self.fd: raise portNotOpenError |
| 297 | t = len(data) |
| 298 | d = data |
| 299 | while t>0: |
| 300 | n = os.write(self.fd, d) |
| 301 | d = d[n:] |
| 302 | t = t - n |
| 303 | |
| 304 | def read(self, size=1): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 305 | """read a number of bytes from the port. |
| 306 | the default is one (unlike files)""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 307 | if not self.fd: raise portNotOpenError |
| 308 | read = '' |
cliechti | 8d5dbe2 | 2002-04-24 20:44:13 +0000 | [diff] [blame] | 309 | inp = None |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 310 | if size > 0: |
| 311 | while len(read) < size: |
cliechti | a9e4e95 | 2002-05-26 01:20:22 +0000 | [diff] [blame] | 312 | #print "\tread(): size",size, "have", len(read) #debug |
| 313 | ready,_,_ = select.select([self.fd],[],[], self.timeout) |
| 314 | if not ready: |
| 315 | break #timeout |
| 316 | buf = os.read(self.fd, size-len(read)) |
| 317 | read = read + buf |
| 318 | if self.timeout >= 0 and not buf: |
| 319 | break #early abort on timeout |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 320 | return read |
| 321 | |
| 322 | def flushInput(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 323 | """clear input queue""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 324 | if not self.fd: |
| 325 | raise portNotOpenError |
| 326 | termios.tcflush(self.fd, TERMIOS.TCIFLUSH) |
| 327 | |
| 328 | def flushOutput(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 329 | """flush output""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 330 | if not self.fd: |
| 331 | raise portNotOpenError |
| 332 | termios.tcflush(self.fd, TERMIOS.TCOFLUSH) |
| 333 | |
| 334 | def sendBreak(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 335 | """send break signal""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 336 | if not self.fd: |
| 337 | raise portNotOpenError |
| 338 | termios.tcsendbreak(self.fd, 0) |
| 339 | |
| 340 | def drainOutput(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 341 | """internal - not portable!""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 342 | if not self.fd: raise portNotOpenError |
| 343 | termios.tcdrain(self.fd) |
| 344 | |
| 345 | def nonblocking(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 346 | """internal - not portable!""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 347 | if not self.fd: |
| 348 | raise portNotOpenError |
| 349 | fcntl.fcntl(self.fd, FCNTL.F_SETFL, FCNTL.O_NONBLOCK) |
| 350 | |
| 351 | def getDSR(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 352 | """read terminal status line""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 353 | if not self.fd: raise portNotOpenError |
| 354 | s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) |
| 355 | return struct.unpack('I',s)[0] & TIOCM_DSR |
| 356 | |
| 357 | def getCD(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 358 | """read terminal status line""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 359 | if not self.fd: raise portNotOpenError |
| 360 | s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) |
| 361 | return struct.unpack('I',s)[0] & TIOCM_CD |
| 362 | |
| 363 | def getRI(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 364 | """read terminal status line""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 365 | if not self.fd: raise portNotOpenError |
| 366 | s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) |
| 367 | return struct.unpack('I',s)[0] & TIOCM_RI |
| 368 | |
| 369 | def getCTS(self): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 370 | """read terminal status line""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 371 | if not self.fd: raise portNotOpenError |
| 372 | s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) |
| 373 | return struct.unpack('I',s)[0] & TIOCM_CTS |
| 374 | |
| 375 | def setDTR(self,on=1): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 376 | """set terminal status line""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 377 | if not self.fd: raise portNotOpenError |
| 378 | if on: |
| 379 | fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str) |
| 380 | else: |
| 381 | fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str) |
| 382 | |
| 383 | def setRTS(self,on=1): |
cliechti | e8f75f9 | 2002-02-14 01:33:33 +0000 | [diff] [blame] | 384 | """set terminal status line""" |
cliechti | 89b4af1 | 2002-02-12 23:24:41 +0000 | [diff] [blame] | 385 | if not self.fd: raise portNotOpenError |
| 386 | if on: |
| 387 | fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str) |
| 388 | else: |
| 389 | fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str) |
| 390 | |
| 391 | if __name__ == '__main__': |
| 392 | s = Serial(0, |
| 393 | baudrate=19200, #baudrate |
| 394 | bytesize=EIGHTBITS, #number of databits |
| 395 | parity=PARITY_EVEN, #enable parity checking |
| 396 | stopbits=STOPBITS_ONE, #number of stopbits |
| 397 | timeout=3, #set a timeout value, None for waiting forever |
| 398 | xonxoff=0, #enable software flow control |
| 399 | rtscts=0, #enable RTS/CTS flow control |
| 400 | ) |
| 401 | s.setRTS(1) |
| 402 | s.setDTR(1) |
| 403 | s.flushInput() |
| 404 | s.flushOutput() |
| 405 | s.write('hello') |
| 406 | print repr(s.read(5)) |
| 407 | print s.inWaiting() |
| 408 | del s |