1.5 stop bit support
diff --git a/pyserial/CHANGES.txt b/pyserial/CHANGES.txt
index cb9debc..d57fa7b 100644
--- a/pyserial/CHANGES.txt
+++ b/pyserial/CHANGES.txt
@@ -301,10 +301,14 @@
 ---------------------------
 New Features:
 
+- 1.5 stop bits (STOPBITS_ONE_POINT_FIVE, implemented on all platforms)
+
 Bugfixes:
 
 - Improve and fix tcp_serial_redirector example.
+- [Bug 2603052] 5-bit mode (needs 1.5 stop bits in some cases)
 
 Bugfixes (win32):
 
 - [Bug 2469098] parity PARITY_MARK, PARITY_SPACE does't supported in win32
+
diff --git a/pyserial/serial/serialcli.py b/pyserial/serial/serialcli.py
index bc3c893..f205502 100644
--- a/pyserial/serial/serialcli.py
+++ b/pyserial/serial/serialcli.py
@@ -51,17 +51,17 @@
         """Set communication parameters on opened port."""
         if not self._port_handle:
             raise SerialException("Can only operate on a valid port handle")
-        
+
         #~ self._port_handle.ReceivedBytesThreshold = 1
-        
+
         if self._timeout is None:
             self._port_handle.ReadTimeout = System.IO.Ports.SerialPort.InfiniteTimeout
         else:
             self._port_handle.ReadTimeout = int(self._timeout*1000)
-            
+
         # if self._timeout != 0 and self._interCharTimeout is not None:
             # timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:]
-            
+
         if self._writeTimeout is None:
             self._port_handle.WriteTimeout = System.IO.Ports.SerialPort.InfiniteTimeout
         else:
@@ -101,11 +101,13 @@
 
         if self._stopbits == STOPBITS_ONE:
             self._port_handle.StopBits     = System.IO.Ports.StopBits.One
+        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:
+            self._port_handle.StopBits     = System.IO.Ports.StopBits.OnePointFive
         elif self._stopbits == STOPBITS_TWO:
             self._port_handle.StopBits     = System.IO.Ports.StopBits.Two
         else:
             raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
-        
+
         if self._rtscts and self._xonxoff:
             self._port_handle.Handshake  = System.IO.Ports.Handshake.RequestToSendXOnXOff
         elif self._rtscts:
@@ -137,7 +139,7 @@
             raise SerialException(str(e))
 
     #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
-    
+
     def inWaiting(self):
         """Return the number of characters currently in the input buffer."""
         if not self._port_handle: raise portNotOpenError
diff --git a/pyserial/serial/serialjava.py b/pyserial/serial/serialjava.py
index cca46dc..ac7c595 100644
--- a/pyserial/serial/serialjava.py
+++ b/pyserial/serial/serialjava.py
@@ -49,7 +49,7 @@
 class Serial(SerialBase):
     """Serial port class, implemented with Java Communications API and
        thus usable with jython and the appropriate java extension."""
-    
+
     def open(self):
         """Open port with current settings. This may throw a SerialException
            if the port cannot be opened."""
@@ -73,7 +73,7 @@
         """Set commuication parameters on opened port."""
         if not self.sPort:
             raise SerialException("Can only operate on a valid port handle")
-        
+
         self.sPort.enableReceiveTimeout(30)
         if self._bytesize == FIVEBITS:
             jdatabits = comm.SerialPort.DATABITS_5
@@ -85,10 +85,10 @@
             jdatabits = comm.SerialPort.DATABITS_8
         else:
             raise ValueError("unsupported bytesize: %r" % self._bytesize)
-        
+
         if self._stopbits == STOPBITS_ONE:
             jstopbits = comm.SerialPort.STOPBITS_1
-        elif stopbits == STOPBITS_ONE_HALVE:
+        elif stopbits == STOPBITS_ONE_POINT_FIVE:
             self._jstopbits = comm.SerialPort.STOPBITS_1_5
         elif self._stopbits == STOPBITS_TWO:
             jstopbits = comm.SerialPort.STOPBITS_2
@@ -115,10 +115,10 @@
         if self._xonxoff:
             jflowin  |=  comm.SerialPort.FLOWCONTROL_XONXOFF_IN
             jflowout |=  comm.SerialPort.FLOWCONTROL_XONXOFF_OUT
-        
+
         self.sPort.setSerialPortParams(baudrate, jdatabits, jstopbits, jparity)
         self.sPort.setFlowControlMode(jflowin | jflowout)
-        
+
         if self._timeout >= 0:
             self.sPort.enableReceiveTimeout(self._timeout*1000)
         else:
diff --git a/pyserial/serial/serialposix.py b/pyserial/serial/serialposix.py
index f66b584..63339b1 100644
--- a/pyserial/serial/serialposix.py
+++ b/pyserial/serial/serialposix.py
@@ -1,9 +1,10 @@
 #!/usr/bin/env python
+#
 # Python Serial Port Extension for Win32, Linux, BSD, Jython
 # module for serial IO for POSIX compatible systems, like Linux
 # see __init__.py
 #
-# (C) 2001-2008 Chris Liechti <cliechti@gmx.net>
+# (C) 2001-2009 Chris Liechti <cliechti@gmx.net>
 # this is distributed under a free software license, see license.txt
 #
 # parts based on code from Grant B. Edwards  <grante@visi.com>:
@@ -61,7 +62,7 @@
 elif plat[:5] == 'sunos':    #Solaris/SunOS (confirmed)
     def device(port):
         return '/dev/tty%c' % (ord('a')+port)
-        
+
 elif plat[:3] == 'aix':      #aix
     def device(port):
         return '/dev/tty%d' % (port)
@@ -81,19 +82,19 @@
 e.g. 'first serial port: /dev/ttyS0'
 and with a bit luck you can get this module running...
 """ % (sys.platform, os.name, VERSION)
-    #no exception, just continue with a brave attempt to build a device name
-    #even if the device name is not correct for the platform it has chances
-    #to work using a string with the real device name as port paramter.
+    # no exception, just continue with a brave attempt to build a device name
+    # even if the device name is not correct for the platform it has chances
+    # to work using a string with the real device name as port paramter.
     def device(portum):
         return '/dev/ttyS%d' % portnum
     #~ raise Exception, "this module does not run on this platform, sorry."
 
-#whats up with "aix", "beos", ....
-#they should work, just need to know the device names.
+# whats up with "aix", "beos", ....
+# they should work, just need to know the device names.
 
 
-#load some constants for later use.
-#try to use values from TERMIOS, use defaults from linux otherwise
+# load some constants for later use.
+# try to use values from TERMIOS, use defaults from linux otherwise
 TIOCMGET  = hasattr(TERMIOS, 'TIOCMGET') and TERMIOS.TIOCMGET or 0x5415
 TIOCMBIS  = hasattr(TERMIOS, 'TIOCMBIS') and TERMIOS.TIOCMBIS or 0x5416
 TIOCMBIC  = hasattr(TERMIOS, 'TIOCMBIC') and TERMIOS.TIOCMBIC or 0x5417
@@ -158,7 +159,7 @@
     3500000: 0010016,
     4000000: 0010017
 }
-    
+
 
 class Serial(SerialBase):
     """Serial port class POSIX implementation. Serial port configuration is 
@@ -171,14 +172,14 @@
         if self._port is None:
             raise SerialException("Port must be configured before it can be used.")
         self.fd = None
-        #open
+        # open
         try:
             self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
         except Exception, msg:
             self.fd = None
             raise SerialException("could not open port %s: %s" % (self._port, msg))
         #~ fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0)  #set blocking
-        
+
         try:
             self._reconfigurePort()
         except:
@@ -187,14 +188,14 @@
         else:
             self._isOpen = True
         #~ self.flushInput()
-        
-        
+
+
     def _reconfigurePort(self):
         """Set communication parameters on opened port."""
         if self.fd is None:
             raise SerialException("Can only operate on a valid port handle")
         custom_baud = None
-        
+
         vmin = vtime = 0                #timeout is done via select
         if self._interCharTimeout is not None:
             vmin = 1
@@ -203,22 +204,22 @@
             iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(self.fd)
         except termios.error, msg:      #if a port is nonexistent but has a /dev file, it'll fail here
             raise SerialException("Could not configure port: %s" % msg)
-        #set up raw mode / no echo / binary
+        # set up raw mode / no echo / binary
         cflag |=  (TERMIOS.CLOCAL|TERMIOS.CREAD)
         lflag &= ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL|
                      TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT
         for flag in ('ECHOCTL', 'ECHOKE'): #netbsd workaround for Erk
             if hasattr(TERMIOS, flag):
                 lflag &= ~getattr(TERMIOS, flag)
-        
+
         oflag &= ~(TERMIOS.OPOST)
         iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)
         if hasattr(TERMIOS, 'IUCLC'):
             iflag &= ~TERMIOS.IUCLC
         if hasattr(TERMIOS, 'PARMRK'):
             iflag &= ~TERMIOS.PARMRK
-        
-        #setup baudrate
+
+        # setup baudrate
         try:
             ispeed = ospeed = getattr(TERMIOS,'B%s' % (self._baudrate))
         except AttributeError:
@@ -229,8 +230,8 @@
                 # may need custom baud rate, it isnt in our list.
                 ispeed = ospeed = getattr(TERMIOS, 'B38400')
                 custom_baud = int(self._baudrate) # store for later
-        
-        #setup char len
+
+        # setup char len
         cflag &= ~TERMIOS.CSIZE
         if self._bytesize == 8:
             cflag |= TERMIOS.CS8
@@ -242,14 +243,16 @@
             cflag |= TERMIOS.CS5
         else:
             raise ValueError('Invalid char len: %r' % self._bytesize)
-        #setup stopbits
+        # setup stopbits
         if self._stopbits == STOPBITS_ONE:
             cflag &= ~(TERMIOS.CSTOPB)
+        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:
+            cflag |=  (TERMIOS.CSTOPB)  # XXX same as TWO.. there is no POSIX support for 1.5
         elif self._stopbits == STOPBITS_TWO:
             cflag |=  (TERMIOS.CSTOPB)
         else:
             raise ValueError('Invalid stopit specification: %r' % self._stopbits)
-        #setup parity
+        # setup parity
         iflag &= ~(TERMIOS.INPCK|TERMIOS.ISTRIP)
         if self._parity == PARITY_NONE:
             cflag &= ~(TERMIOS.PARENB|TERMIOS.PARODD)
@@ -260,8 +263,8 @@
             cflag |=  (TERMIOS.PARENB|TERMIOS.PARODD)
         else:
             raise ValueError('Invalid parity: %r' % self._parity)
-        #setup flow control
-        #xonxoff
+        # setup flow control
+        # xonxoff
         if hasattr(TERMIOS, 'IXANY'):
             if self._xonxoff:
                 iflag |=  (TERMIOS.IXON|TERMIOS.IXOFF) #|TERMIOS.IXANY)
@@ -272,7 +275,7 @@
                 iflag |=  (TERMIOS.IXON|TERMIOS.IXOFF)
             else:
                 iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF)
-        #rtscts
+        # rtscts
         if hasattr(TERMIOS, 'CRTSCTS'):
             if self._rtscts:
                 cflag |=  (TERMIOS.CRTSCTS)
@@ -284,19 +287,19 @@
             else:
                 cflag &= ~(TERMIOS.CNEW_RTSCTS)
         #XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
-        
-        #buffer
-        #vmin "minimal number of characters to be read. = for non blocking"
+
+        # buffer
+        # vmin "minimal number of characters to be read. = for non blocking"
         if vmin < 0 or vmin > 255:
             raise ValueError('Invalid vmin: %r ' % vmin)
         cc[TERMIOS.VMIN] = vmin
-        #vtime
+        # vtime
         if vtime < 0 or vtime > 255:
             raise ValueError('Invalid vtime: %r' % vtime)
         cc[TERMIOS.VTIME] = vtime
-        #activate settings
+        # activate settings
         termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
-        
+
         # apply custom baud rate, if any
         if custom_baud is not None:
             import array
@@ -346,14 +349,14 @@
         inp = None
         if size > 0:
             while len(read) < size:
-                #print "\tread(): size",size, "have", len(read)    #debug
+                # print "\tread(): size",size, "have", len(read)    #debug
                 ready,_,_ = select.select([self.fd],[],[], self._timeout)
                 if not ready:
-                    break   #timeout
+                    break   # timeout
                 buf = os.read(self.fd, size-len(read))
                 read = read + buf
                 if (self._timeout >= 0 or self._interCharTimeout > 0) and not buf:
-                    break  #early abort on timeout
+                    break   # early abort on timeout
         return read
 
     def write(self, data):
diff --git a/pyserial/serial/serialutil.py b/pyserial/serial/serialutil.py
index edba0a0..a1de7c5 100644
--- a/pyserial/serial/serialutil.py
+++ b/pyserial/serial/serialutil.py
@@ -6,7 +6,7 @@
 # this is distributed under a free software license, see license.txt
 
 PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = 'N', 'E', 'O', 'M', 'S'
-STOPBITS_ONE, STOPBITS_TWO = (1, 2)
+STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO = (1, 1.5, 2)
 FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)
 
 PARITY_NAMES = {
diff --git a/pyserial/serial/serialwin32.py b/pyserial/serial/serialwin32.py
index b6f15f4..fac84f0 100644
--- a/pyserial/serial/serialwin32.py
+++ b/pyserial/serial/serialwin32.py
@@ -140,6 +140,8 @@
 
         if self._stopbits == STOPBITS_ONE:
             comDCB.StopBits     = win32file.ONESTOPBIT
+        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:
+            comDCB.StopBits     = win32file.ONE5STOPBITS
         elif self._stopbits == STOPBITS_TWO:
             comDCB.StopBits     = win32file.TWOSTOPBITS
         else: