15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#!/usr/bin/env python 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Python Serial Port Extension for Win32, Linux, BSD, Jython 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# module for serial IO for POSIX compatible systems, like Linux 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# see __init__.py 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# (C) 2001-2010 Chris Liechti <cliechti@gmx.net> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# this is distributed under a free software license, see license.txt 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# parts based on code from Grant B. Edwards <grante@visi.com>: 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# ftp://ftp.visi.com/users/grante/python/PosixSerial.py 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# references: http://www.easysw.com/~mike/serial/serial.html 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import sys, os, fcntl, termios, struct, select, errno, time 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from serial.serialutil import * 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Do check the Python version as some constants have moved. 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)if (sys.hexversion < 0x020100f0): 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import TERMIOS 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)else: 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TERMIOS = termios 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)if (sys.hexversion < 0x020200f0): 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import FCNTL 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)else: 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FCNTL = fcntl 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# try to detect the OS so that a device can be selected... 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# this code block should supply a device() and set_special_baudrate() function 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# for the platform 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)plat = sys.platform.lower() 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)if plat[:5] == 'linux': # Linux (confirmed) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/ttyS%d' % port 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TCGETS2 = 0x802C542A 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TCSETS2 = 0x402C542B 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BOTHER = 0o010000 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # right size is 44 on x86_64, allow for some growth 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import array 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf = array.array('i', [0] * 64) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # get serial_struct 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FCNTL.ioctl(port.fd, TCGETS2, buf) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # set custom speed 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf[2] &= ~TERMIOS.CBAUD 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf[2] |= BOTHER 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf[9] = buf[10] = baudrate 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # set serial_struct 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) res = FCNTL.ioctl(port.fd, TCSETS2, buf) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except IOError, e: 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Failed to set custom baud rate (%s): %s' % (baudrate, e)) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0: 0000000, # hang up 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 50: 0000001, 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75: 0000002, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 110: 0000003, 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 134: 0000004, 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 150: 0000005, 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 200: 0000006, 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 300: 0000007, 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 600: 0000010, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1200: 0000011, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1800: 0000012, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2400: 0000013, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4800: 0000014, 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9600: 0000015, 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 19200: 0000016, 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 38400: 0000017, 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 57600: 0010001, 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115200: 0010002, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 230400: 0010003, 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 460800: 0010004, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 500000: 0010005, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 576000: 0010006, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 921600: 0010007, 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1000000: 0010010, 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1152000: 0010011, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1500000: 0010012, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2000000: 0010013, 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2500000: 0010014, 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3000000: 0010015, 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3500000: 0010016, 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4000000: 0010017 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat == 'cygwin': # cygwin/win32 (confirmed) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/com%d' % (port + 1) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = { 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 128000: 0x01003, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 256000: 0x01005, 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 500000: 0x01007, 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 576000: 0x01008, 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 921600: 0x01009, 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1000000: 0x0100a, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1152000: 0x0100b, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1500000: 0x0100c, 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2000000: 0x0100d, 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2500000: 0x0100e, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3000000: 0x0100f 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:7] == 'openbsd': # OpenBSD 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/cua%02d' % port 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:3] == 'bsd' or \ 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) plat[:7] == 'freebsd': 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/cuad%d' % port 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:6] == 'darwin': # OS X 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version = os.uname()[2].split('.') 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Tiger or above can support arbitrary serial speeds 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if int(version[0]) >= 8: 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # use IOKit-specific call to set up high speeds 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import array, fcntl 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf = array.array('i', [baudrate]) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IOSSIOSPEED = 0x80045402 #_IOW('T', 2, speed_t) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(port.fd, IOSSIOSPEED, buf, 1) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: # version < 8 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("baud rate not supported") 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/cuad%d' % port 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:6] == 'netbsd': # NetBSD 1.6 testing by Erk 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/dty%02d' % port 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:4] == 'irix': # IRIX (partially tested) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/ttyf%d' % (port+1) #XXX different device names depending on flow control 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:2] == 'hp': # HP-UX (not tested) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/tty%dp0' % (port+1) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:5] == 'sunos': # Solaris/SunOS (confirmed) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/tty%c' % (ord('a')+port) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)elif plat[:3] == 'aix': # AIX 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(port): 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/tty%d' % (port) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError("sorry don't know how to handle non standard baud rate on this platform") 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)else: 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # platform detection has failed... 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sys.stderr.write("""\ 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)don't know how to number ttys on this system. 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)! Use an explicit path (eg /dev/ttyS1) or send this information to 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)! the author of this module: 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)sys.platform = %r 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)os.name = %r 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)serialposix.py version = %s 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)also add the device name of the serial port and where the 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)counting starts for the first serial port. 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)e.g. 'first serial port: /dev/ttyS0' 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)and with a bit luck you can get this module running... 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""" % (sys.platform, os.name, VERSION)) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # no exception, just continue with a brave attempt to build a device name 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # even if the device name is not correct for the platform it has chances 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # to work using a string with the real device name as port parameter. 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def device(portum): 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '/dev/ttyS%d' % portnum 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_special_baudrate(port, baudrate): 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException("sorry don't know how to handle non standard baud rate on this platform") 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate_constants = {} 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) #~ raise Exception, "this module does not run on this platform, sorry." 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# whats up with "aix", "beos", .... 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# they should work, just need to know the device names. 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# load some constants for later use. 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# try to use values from TERMIOS, use defaults from linux otherwise 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCMGET = hasattr(TERMIOS, 'TIOCMGET') and TERMIOS.TIOCMGET or 0x5415 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCMBIS = hasattr(TERMIOS, 'TIOCMBIS') and TERMIOS.TIOCMBIS or 0x5416 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCMBIC = hasattr(TERMIOS, 'TIOCMBIC') and TERMIOS.TIOCMBIC or 0x5417 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCMSET = hasattr(TERMIOS, 'TIOCMSET') and TERMIOS.TIOCMSET or 0x5418 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#TIOCM_LE = hasattr(TERMIOS, 'TIOCM_LE') and TERMIOS.TIOCM_LE or 0x001 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_DTR = hasattr(TERMIOS, 'TIOCM_DTR') and TERMIOS.TIOCM_DTR or 0x002 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_RTS = hasattr(TERMIOS, 'TIOCM_RTS') and TERMIOS.TIOCM_RTS or 0x004 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#TIOCM_ST = hasattr(TERMIOS, 'TIOCM_ST') and TERMIOS.TIOCM_ST or 0x008 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#TIOCM_SR = hasattr(TERMIOS, 'TIOCM_SR') and TERMIOS.TIOCM_SR or 0x010 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_CTS = hasattr(TERMIOS, 'TIOCM_CTS') and TERMIOS.TIOCM_CTS or 0x020 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_CAR = hasattr(TERMIOS, 'TIOCM_CAR') and TERMIOS.TIOCM_CAR or 0x040 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_RNG = hasattr(TERMIOS, 'TIOCM_RNG') and TERMIOS.TIOCM_RNG or 0x080 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_DSR = hasattr(TERMIOS, 'TIOCM_DSR') and TERMIOS.TIOCM_DSR or 0x100 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_CD = hasattr(TERMIOS, 'TIOCM_CD') and TERMIOS.TIOCM_CD or TIOCM_CAR 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_RI = hasattr(TERMIOS, 'TIOCM_RI') and TERMIOS.TIOCM_RI or TIOCM_RNG 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#TIOCM_OUT1 = hasattr(TERMIOS, 'TIOCM_OUT1') and TERMIOS.TIOCM_OUT1 or 0x2000 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#TIOCM_OUT2 = hasattr(TERMIOS, 'TIOCM_OUT2') and TERMIOS.TIOCM_OUT2 or 0x4000 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)if hasattr(TERMIOS, 'TIOCINQ'): 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TIOCINQ = TERMIOS.TIOCINQ 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)else: 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TIOCINQ = hasattr(TERMIOS, 'FIONREAD') and TERMIOS.FIONREAD or 0x541B 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCOUTQ = hasattr(TERMIOS, 'TIOCOUTQ') and TERMIOS.TIOCOUTQ or 0x5411 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_zero_str = struct.pack('I', 0) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_RTS_str = struct.pack('I', TIOCM_RTS) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCM_DTR_str = struct.pack('I', TIOCM_DTR) 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCSBRK = hasattr(TERMIOS, 'TIOCSBRK') and TERMIOS.TIOCSBRK or 0x5427 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TIOCCBRK = hasattr(TERMIOS, 'TIOCCBRK') and TERMIOS.TIOCCBRK or 0x5428 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PosixSerial(SerialBase): 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Serial port class POSIX implementation. Serial port configuration is 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) done with termios and fcntl. Runs on Linux and many other Un*x like 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) systems.""" 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def open(self): 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Open port with current settings. This may throw a SerialException 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if the port cannot be opened.""" 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._port is None: 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException("Port must be configured before it can be used.") 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._isOpen: 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException("Port is already open.") 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.fd = None 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # open 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except IOError, msg: 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.fd = None 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException(msg.errno, "could not open port %s: %s" % (self._port, msg)) 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) #~ fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) # set blocking 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._reconfigurePort() 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except: 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) os.close(self.fd) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except: 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # ignore any exception when closing the port 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # also to keep original exception that happened when setting up 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pass 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.fd = None 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._isOpen = True 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.flushInput() 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _reconfigurePort(self): 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Set communication parameters on opened port.""" 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.fd is None: 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException("Can only operate on a valid file descriptor") 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) custom_baud = None 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) vmin = vtime = 0 # timeout is done via select 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._interCharTimeout is not None: 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) vmin = 1 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) vtime = int(self._interCharTimeout * 10) 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) orig_attr = termios.tcgetattr(self.fd) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except termios.error, msg: # if a port is nonexistent but has a /dev file, it'll fail here 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException("Could not configure port: %s" % msg) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # set up raw mode / no echo / binary 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.CLOCAL|TERMIOS.CREAD) 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) lflag &= ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL| 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if hasattr(TERMIOS, flag): 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) lflag &= ~getattr(TERMIOS, flag) 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) oflag &= ~(TERMIOS.OPOST) 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK) 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if hasattr(TERMIOS, 'IUCLC'): 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag &= ~TERMIOS.IUCLC 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if hasattr(TERMIOS, 'PARMRK'): 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag &= ~TERMIOS.PARMRK 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # setup baud rate 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ispeed = ospeed = getattr(TERMIOS, 'B%s' % (self._baudrate)) 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except AttributeError: 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ispeed = ospeed = baudrate_constants[self._baudrate] 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except KeyError: 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) #~ raise ValueError('Invalid baud rate: %r' % self._baudrate) 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # may need custom baud rate, it isn't in our list. 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ispeed = ospeed = getattr(TERMIOS, 'B38400') 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) custom_baud = int(self._baudrate) # store for later 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except ValueError: 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid baud rate: %r' % self._baudrate) 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if custom_baud < 0: 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid baud rate: %r' % self._baudrate) 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # setup char len 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag &= ~TERMIOS.CSIZE 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._bytesize == 8: 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= TERMIOS.CS8 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._bytesize == 7: 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= TERMIOS.CS7 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._bytesize == 6: 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= TERMIOS.CS6 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._bytesize == 5: 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= TERMIOS.CS5 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid char len: %r' % self._bytesize) 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # setup stopbits 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._stopbits == STOPBITS_ONE: 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag &= ~(TERMIOS.CSTOPB) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._stopbits == STOPBITS_ONE_POINT_FIVE: 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.CSTOPB) # XXX same as TWO.. there is no POSIX support for 1.5 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._stopbits == STOPBITS_TWO: 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.CSTOPB) 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid stop bit specification: %r' % self._stopbits) 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # setup parity 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag &= ~(TERMIOS.INPCK|TERMIOS.ISTRIP) 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._parity == PARITY_NONE: 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag &= ~(TERMIOS.PARENB|TERMIOS.PARODD) 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._parity == PARITY_EVEN: 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag &= ~(TERMIOS.PARODD) 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.PARENB) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self._parity == PARITY_ODD: 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.PARENB|TERMIOS.PARODD) 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid parity: %r' % self._parity) 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # setup flow control 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # xonxoff 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if hasattr(TERMIOS, 'IXANY'): 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._xonxoff: 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag |= (TERMIOS.IXON|TERMIOS.IXOFF) #|TERMIOS.IXANY) 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY) 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._xonxoff: 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag |= (TERMIOS.IXON|TERMIOS.IXOFF) 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF) 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # rtscts 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if hasattr(TERMIOS, 'CRTSCTS'): 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._rtscts: 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.CRTSCTS) 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag &= ~(TERMIOS.CRTSCTS) 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif hasattr(TERMIOS, 'CNEW_RTSCTS'): # try it with alternate constant name 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._rtscts: 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag |= (TERMIOS.CNEW_RTSCTS) 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cflag &= ~(TERMIOS.CNEW_RTSCTS) 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails?? 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # buffer 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # vmin "minimal number of characters to be read. = for non blocking" 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if vmin < 0 or vmin > 255: 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid vmin: %r ' % vmin) 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cc[TERMIOS.VMIN] = vmin 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # vtime 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if vtime < 0 or vtime > 255: 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Invalid vtime: %r' % vtime) 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cc[TERMIOS.VTIME] = vtime 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # activate settings 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr: 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]) 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # apply custom baud rate, if any 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if custom_baud is not None: 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_special_baudrate(self, custom_baud) 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def close(self): 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Close port""" 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._isOpen: 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.fd is not None: 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) os.close(self.fd) 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.fd = None 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._isOpen = False 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def makeDeviceName(self, port): 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return device(port) 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # - - - - - - - - - - - - - - - - - - - - - - - - 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def inWaiting(self): 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Return the number of characters currently in the input buffer.""" 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) #~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str) 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str) 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return struct.unpack('I',s)[0] 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # select based implementation, proved to work on many systems 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def read(self, size=1): 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read size bytes from the serial port. If a timeout is set it may 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return less characters as requested. With no timeout it will block 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) until the requested number of bytes is read.""" 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) read = bytearray() 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while len(read) < size: 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ready,_,_ = select.select([self.fd],[],[], self._timeout) 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # If select was used with a timeout, and the timeout occurs, it 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # returns with empty lists -> thus abort read operation. 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # For timeout == 0 (non-blocking operation) also abort when there 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # is nothing to read. 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not ready: 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break # timeout 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf = os.read(self.fd, size-len(read)) 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # read should always return some data as select reported it was 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # ready to read when we get to this point. 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not buf: 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Disconnected devices, at least on Linux, show the 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # behavior that they are always ready to read immediately 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # but reading returns nothing. 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException('device reports readiness to read but returned no data (device disconnected or multiple access on port?)') 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) read.extend(buf) 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except select.error, e: 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # ignore EAGAIN errors. all other errors are shown 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # see also http://www.python.org/dev/peps/pep-3151/#select 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if e[0] != errno.EAGAIN: 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException('read failed: %s' % (e,)) 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except OSError, e: 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # ignore EAGAIN errors. all other errors are shown 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if e.errno != errno.EAGAIN: 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException('read failed: %s' % (e,)) 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return bytes(read) 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def write(self, data): 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Output the given string over the serial port.""" 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d = to_bytes(data) 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tx_len = len(d) 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._writeTimeout is not None and self._writeTimeout > 0: 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timeout = time.time() + self._writeTimeout 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timeout = None 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while tx_len > 0: 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) n = os.write(self.fd, d) 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if timeout: 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # when timeout is set, use select to wait for being ready 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # with the time left as timeout 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timeleft = timeout - time.time() 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if timeleft < 0: 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise writeTimeoutError 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _, ready, _ = select.select([], [self.fd], [], timeleft) 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not ready: 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise writeTimeoutError 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # wait for write operation 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _, ready, _ = select.select([], [self.fd], [], None) 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not ready: 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException('write failed (select)') 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d = d[n:] 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tx_len -= n 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except OSError, v: 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if v.errno != errno.EAGAIN: 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException('write failed: %s' % (v,)) 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return len(data) 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def flush(self): 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Flush of file like objects. In this case, wait until all data 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is written.""" 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.drainOutput() 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def flushInput(self): 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Clear input buffer, discarding all that is in the buffer.""" 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcflush(self.fd, TERMIOS.TCIFLUSH) 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def flushOutput(self): 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Clear output buffer, aborting the current output and 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) discarding all that is in the buffer.""" 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcflush(self.fd, TERMIOS.TCOFLUSH) 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def sendBreak(self, duration=0.25): 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Send break condition. Timed, returns to idle state after given duration.""" 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcsendbreak(self.fd, int(duration/0.25)) 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def setBreak(self, level=1): 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Set break: Controls TXD. When active, no transmitting is possible.""" 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.fd is None: raise portNotOpenError 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if level: 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(self.fd, TIOCSBRK) 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(self.fd, TIOCCBRK) 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def setRTS(self, level=1): 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Set terminal status line: Request To Send""" 5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if level: 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str) 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str) 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def setDTR(self, level=1): 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Set terminal status line: Data Terminal Ready""" 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if level: 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str) 5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str) 5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def getCTS(self): 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read terminal status line: Clear To Send""" 5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return struct.unpack('I',s)[0] & TIOCM_CTS != 0 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def getDSR(self): 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read terminal status line: Data Set Ready""" 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return struct.unpack('I',s)[0] & TIOCM_DSR != 0 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def getRI(self): 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read terminal status line: Ring Indicator""" 5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return struct.unpack('I',s)[0] & TIOCM_RI != 0 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def getCD(self): 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read terminal status line: Carrier Detect""" 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return struct.unpack('I',s)[0] & TIOCM_CD != 0 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # - - platform specific - - - - 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def outWaiting(self): 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Return the number of characters currently in the output buffer.""" 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) #~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str) 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = fcntl.ioctl(self.fd, TIOCOUTQ, TIOCM_zero_str) 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return struct.unpack('I',s)[0] 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def drainOutput(self): 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """internal - not portable!""" 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcdrain(self.fd) 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def nonblocking(self): 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """internal - not portable!""" 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fcntl.fcntl(self.fd, FCNTL.F_SETFL, os.O_NONBLOCK) 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def fileno(self): 6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """\ 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) For easier use of the serial port instance with select. 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WARNING: this function is not portable to different platforms! 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.fd 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def setXON(self, level=True): 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """\ 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Manually control flow - when software flow control is enabled. 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) This will send XON (true) and XOFF (false) to the other device. 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WARNING: this function is not portable to different platforms! 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self.hComPort: raise portNotOpenError 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if enable: 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcflow(self.fd, TERMIOS.TCION) 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcflow(self.fd, TERMIOS.TCIOFF) 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def flowControlOut(self, enable): 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """\ 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Manually control flow of outgoing data - when hardware or software flow 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) control is enabled. 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WARNING: this function is not portable to different platforms! 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self._isOpen: raise portNotOpenError 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if enable: 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcflow(self.fd, TERMIOS.TCOON) 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) termios.tcflow(self.fd, TERMIOS.TCOOFF) 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# assemble Serial class with the platform specifc implementation and the base 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# for file-like behavior. for Python 2.6 and newer, that provide the new I/O 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# library, derrive from io.RawIOBase 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)try: 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import io 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)except ImportError: 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # classic version with our own file-like emulation 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class Serial(PosixSerial, FileLike): 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pass 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)else: 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # io library present 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class Serial(PosixSerial, io.RawIOBase): 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pass 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PosixPollSerial(Serial): 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """poll based read implementation. not all systems support poll properly. 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) however this one has better handling of errors, such as a device 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disconnecting while it's in use (e.g. USB-serial unplugged)""" 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def read(self, size=1): 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read size bytes from the serial port. If a timeout is set it may 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return less characters as requested. With no timeout it will block 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) until the requested number of bytes is read.""" 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.fd is None: raise portNotOpenError 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) read = bytearray() 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) poll = select.poll() 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) poll.register(self.fd, select.POLLIN|select.POLLERR|select.POLLHUP|select.POLLNVAL) 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if size > 0: 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while len(read) < size: 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # print "\tread(): size",size, "have", len(read) #debug 6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # wait until device becomes ready to read (or something fails) 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for fd, event in poll.poll(self._timeout*1000): 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if event & (select.POLLERR|select.POLLHUP|select.POLLNVAL): 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise SerialException('device reports error (poll)') 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # we don't care if it is select.POLLIN or timeout, that's 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # handled below 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf = os.read(self.fd, size - len(read)) 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) read.extend(buf) 6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((self._timeout is not None and self._timeout >= 0) or 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (self._interCharTimeout is not None and self._interCharTimeout > 0)) and not buf: 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break # early abort on timeout 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return bytes(read) 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)if __name__ == '__main__': 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s = Serial(0, 6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) baudrate=19200, # baud rate 6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bytesize=EIGHTBITS, # number of data bits 6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) parity=PARITY_EVEN, # enable parity checking 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stopbits=STOPBITS_ONE, # number of stop bits 6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timeout=3, # set a timeout value, None for waiting forever 6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xonxoff=0, # enable software flow control 6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rtscts=0, # enable RTS/CTS flow control 6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ) 6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s.setRTS(1) 6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s.setDTR(1) 6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s.flushInput() 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s.flushOutput() 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s.write('hello') 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sys.stdout.write('%r\n' % s.read(5)) 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sys.stdout.write('%s\n' % s.inWaiting()) 7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) del s 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 704